diff --git a/shaders/reign.v.glsl b/shaders/reign.v.glsl index 60fd555..c0a4064 100644 --- a/shaders/reign.v.glsl +++ b/shaders/reign.v.glsl @@ -42,6 +42,8 @@ uniform vec2 uv_scroll; #endif // ENGINE == REIGN_ENGINE +uniform vec4 uv_tiling; + #if ENABLE_LIGHT_SCATTERING uniform int fog_type; uniform vec4 ls_params; // (beta_r, beta_m, g, distance) @@ -128,11 +130,11 @@ void main() { vec4 view_pos = view_transform * world_pos; gl_Position = proj_transform * view_pos; - tex_coord = vertex_uv + uv_scroll; + tex_coord = (vertex_uv + uv_scroll) * uv_tiling.xy; light_tex_coord = vertex_light_uv + uv_scroll; color_mod = vertex_color; blend_weight = vertex_blend_weight; - blend_tex_coord = vertex_blend_uv + uv_scroll; + blend_tex_coord = (vertex_blend_uv + uv_scroll) * uv_tiling.zw; 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 f3ae67e..cc76f09 100644 --- a/src/3d/3d_internal.h +++ b/src/3d/3d_internal.h @@ -70,6 +70,8 @@ struct mesh { struct material { uint32_t flags; bool is_transparent; + vec2 uv_tiling; + vec2 blend_uv_tiling; int nr_color_maps; GLuint *color_maps; GLuint specular_map; @@ -199,6 +201,7 @@ struct RE_renderer { GLint alpha_mode; GLint alpha_texture; GLint uv_scroll; + GLint uv_tiling; GLint blend_tex; GLint use_blend_texture; @@ -658,6 +661,7 @@ struct pol_material { char *name; uint32_t flags; char *textures[MAX_TEXTURE_TYPE]; + vec2 uv_tiling; }; struct pol_material_group { diff --git a/src/3d/model.c b/src/3d/model.c index 05de49c..c7d9859 100644 --- a/src/3d/model.c +++ b/src/3d/model.c @@ -143,9 +143,11 @@ static GLuint *load_texture_list(struct archive *aar, const char *path, const ch return textures; } -static bool init_material(struct material *material, const struct pol_material *m, struct amt *amt, struct archive *aar, const char *path) +static bool init_material(struct material *material, struct pol_material *m, struct amt *amt, struct archive *aar, const char *path) { material->flags = m->flags; + glm_vec2_copy(m->uv_tiling, material->uv_tiling); + glm_vec2_one(material->blend_uv_tiling); if (!m->textures[COLOR_MAP]) { WARNING("No color texture"); return false; @@ -575,6 +577,8 @@ struct model *model_load(struct archive *aar, const char *path) if (child->children[1].m.textures[COLOR_MAP]) { model->materials[material_offsets[i] + j].blend_texture = load_texture(aar, path, child->children[1].m.textures[COLOR_MAP], NULL); + glm_vec2_copy(child->children[1].m.uv_tiling, + model->materials[material_offsets[i] + j].blend_uv_tiling); } } else { init_material(&model->materials[material_offsets[i] + j], @@ -735,6 +739,8 @@ struct model *model_create_sphere(int r, int g, int b, int a) model->materials = xcalloc(1, sizeof(struct material)); struct material *material = &model->materials[0]; material->is_transparent = true; + glm_vec2_one(material->uv_tiling); + glm_vec2_one(material->blend_uv_tiling); material->color_maps = xmalloc(sizeof(GLuint)); material->nr_color_maps = 1; glGenTextures(1, material->color_maps); diff --git a/src/3d/parser.c b/src/3d/parser.c index 2d23959..e37d04b 100644 --- a/src/3d/parser.c +++ b/src/3d/parser.c @@ -72,14 +72,20 @@ static uint32_t parse_material_attributes(const char *name) static void parse_textures(struct buffer *r, int pol_version, struct pol_material *m) { + glm_vec2_one(m->uv_tiling); int nr_textures = buffer_read_int32(r); for (int i = 0; i < nr_textures; i++) { char *filename = read_cstring(r); int type = buffer_read_int32(r); - if (pol_version >= 3) - buffer_skip(r, 8); // 2 unknown float params + vec2 uv_tiling = { 1.0f, 1.0f }; + if (pol_version >= 3) { + uv_tiling[0] = buffer_read_float(r); + uv_tiling[1] = buffer_read_float(r); + } if ((unsigned)type < MAX_TEXTURE_TYPE) { m->textures[type] = filename; + if (type == COLOR_MAP) + glm_vec2_copy(uv_tiling, m->uv_tiling); } else { WARNING("invalid texture type %d", type); free(filename); diff --git a/src/3d/renderer.c b/src/3d/renderer.c index afbdb12..78fd729 100644 --- a/src/3d/renderer.c +++ b/src/3d/renderer.c @@ -287,6 +287,7 @@ struct RE_renderer *RE_renderer_new(void) r->alpha_mode = glGetUniformLocation(r->program, "alpha_mode"); r->alpha_texture = glGetUniformLocation(r->program, "alpha_texture"); r->uv_scroll = glGetUniformLocation(r->program, "uv_scroll"); + r->uv_tiling = glGetUniformLocation(r->program, "uv_tiling"); r->blend_tex = glGetUniformLocation(r->program, "blend_tex"); r->use_blend_texture = glGetUniformLocation(r->program, "use_blend_texture"); @@ -574,6 +575,9 @@ static void render_model(struct RE_instance *inst, struct RE_renderer *r, enum d vec2 uv_scroll; glm_vec2_scale(mesh->uv_scroll, r->last_frame_timestamp / 1000.f, uv_scroll); glUniform2fv(r->uv_scroll, 1, uv_scroll); + glUniform4f(r->uv_tiling, + material->uv_tiling[0], material->uv_tiling[1], + material->blend_uv_tiling[0], material->blend_uv_tiling[1]); glBindVertexArray(mesh->vao); @@ -630,6 +634,7 @@ static void reset_draw_uniforms(struct RE_renderer *r, struct RE_plugin *plugin) glUniform1f(r->alpha_mod, 1.0f); glUniform3f(r->diffuse_mod, 1.0f, 1.0f, 1.0f); glUniform2f(r->uv_scroll, 0.0f, 0.0f); + glUniform4f(r->uv_tiling, 1.0f, 1.0f, 1.0f, 1.0f); glUniform1i(r->has_bones, GL_FALSE); glUniform3f(r->specular_color, 0.0f, 0.0f, 0.0f); glUniform1f(r->specular_shininess, 0.0f); @@ -779,6 +784,9 @@ static void render_polygon_particles(struct RE_renderer *r, struct RE_instance * for (int i = 0; i < model->nr_meshes; i++) { struct mesh *mesh = &model->meshes[i]; struct material *material = &model->materials[mesh->material]; + glUniform4f(r->uv_tiling, + material->uv_tiling[0], material->uv_tiling[1], + material->blend_uv_tiling[0], material->blend_uv_tiling[1]); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, material->color_maps[0]); @@ -882,6 +890,9 @@ static void render_s3de_polygon_particles(struct RE_renderer *r, struct RE_insta if (phase != (is_transparent ? DRAW_TRANSPARENT : DRAW_OPAQUE)) continue; struct material *material = &model->materials[mesh->material]; + glUniform4f(r->uv_tiling, + material->uv_tiling[0], material->uv_tiling[1], + material->blend_uv_tiling[0], material->blend_uv_tiling[1]); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, material->color_maps[0]);