mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-03 20:38:13 +03:00
ReignEngine: Implement light mapping
This commit is contained in:
@@ -24,6 +24,7 @@ struct dir_light {
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D specular_texture;
|
||||
uniform sampler2D light_texture;
|
||||
uniform float alpha_mod;
|
||||
|
||||
uniform bool use_normal_map;
|
||||
@@ -36,8 +37,10 @@ uniform float specular_shininess;
|
||||
uniform bool use_specular_map;
|
||||
uniform float rim_exponent;
|
||||
uniform vec3 rim_color;
|
||||
uniform bool use_light_map;
|
||||
|
||||
in vec2 tex_coord;
|
||||
in vec2 light_tex_coord;
|
||||
in vec3 frag_pos;
|
||||
in vec3 eye;
|
||||
in vec3 normal;
|
||||
@@ -63,6 +66,9 @@ void main() {
|
||||
float half_lambert = dot(norm, -light_dir[i]) * 0.5 + 0.5;
|
||||
diffuse += mix(dir_lights[i].globe_diffuse, dir_lights[i].diffuse, half_lambert);
|
||||
}
|
||||
if (use_light_map) {
|
||||
diffuse *= texture(light_texture, light_tex_coord).rgb;
|
||||
}
|
||||
vec4 texel = texture(tex, tex_coord);
|
||||
frag_rgb += texel.rgb * diffuse;
|
||||
|
||||
|
||||
@@ -41,11 +41,13 @@ uniform vec3 specular_light_dir;
|
||||
in vec3 vertex_pos;
|
||||
in vec3 vertex_normal;
|
||||
in vec2 vertex_uv;
|
||||
in vec2 vertex_light_uv;
|
||||
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 frag_pos;
|
||||
out vec3 eye;
|
||||
out vec3 normal;
|
||||
@@ -82,6 +84,7 @@ void main() {
|
||||
gl_Position = proj_transform * view_transform * world_pos;
|
||||
|
||||
tex_coord = vertex_uv;
|
||||
light_tex_coord = vertex_light_uv;
|
||||
|
||||
// These are in tangent-space if use_normal_map is true, in world-space
|
||||
// otherwise.
|
||||
|
||||
@@ -48,6 +48,7 @@ struct mesh {
|
||||
struct material {
|
||||
GLuint color_map;
|
||||
GLuint specular_map;
|
||||
GLuint light_map;
|
||||
GLuint normal_map;
|
||||
float specular_strength;
|
||||
float specular_shininess;
|
||||
@@ -98,12 +99,15 @@ struct RE_renderer {
|
||||
GLint rim_exponent;
|
||||
GLint rim_color;
|
||||
GLint view_pos;
|
||||
GLint use_light_map;
|
||||
GLint light_texture;
|
||||
GLint use_normal_map;
|
||||
GLint normal_texture;
|
||||
|
||||
// Attribute variable locations
|
||||
GLint vertex_normal;
|
||||
GLint vertex_uv;
|
||||
GLint vertex_light_uv;
|
||||
GLint vertex_tangent;
|
||||
GLint vertex_bone_index;
|
||||
GLint vertex_bone_weight;
|
||||
@@ -148,6 +152,7 @@ struct pol {
|
||||
enum pol_texture_type {
|
||||
COLOR_MAP = 1,
|
||||
SPECULAR_MAP = 4,
|
||||
LIGHT_MAP = 7,
|
||||
NORMAL_MAP = 8,
|
||||
MAX_TEXTURE_TYPE
|
||||
};
|
||||
@@ -170,6 +175,8 @@ struct pol_mesh {
|
||||
struct pol_vertex *vertices;
|
||||
uint32_t nr_uvs;
|
||||
vec2 *uvs;
|
||||
uint32_t nr_light_uvs;
|
||||
vec2 *light_uvs;
|
||||
uint32_t nr_triangles;
|
||||
struct pol_triangle *triangles;
|
||||
};
|
||||
@@ -188,6 +195,7 @@ struct pol_bone_weight {
|
||||
struct pol_triangle {
|
||||
uint32_t vert_index[3];
|
||||
uint32_t uv_index[3];
|
||||
uint32_t light_uv_index[3];
|
||||
vec3 normals[3];
|
||||
uint32_t material; // index in the material group
|
||||
};
|
||||
|
||||
+25
-4
@@ -35,6 +35,10 @@ struct vertex_common {
|
||||
GLfloat uv[2];
|
||||
};
|
||||
|
||||
struct vertex_light_uv {
|
||||
GLfloat uv[2];
|
||||
};
|
||||
|
||||
struct vertex_tangent {
|
||||
GLfloat tangent[4];
|
||||
};
|
||||
@@ -92,12 +96,12 @@ static bool init_material(struct material *material, const struct pol_material *
|
||||
if (!material->color_map)
|
||||
return false;
|
||||
|
||||
if (m->textures[SPECULAR_MAP]) {
|
||||
if (m->textures[SPECULAR_MAP])
|
||||
material->specular_map = load_texture(aar, path, m->textures[SPECULAR_MAP]);
|
||||
}
|
||||
if (m->textures[NORMAL_MAP]) {
|
||||
if (m->textures[LIGHT_MAP])
|
||||
material->light_map = load_texture(aar, path, m->textures[LIGHT_MAP]);
|
||||
if (m->textures[NORMAL_MAP])
|
||||
material->normal_map = load_texture(aar, path, m->textures[NORMAL_MAP]);
|
||||
}
|
||||
|
||||
struct amt_material *amt_m = amt ? amt_find_material(amt, m->name) : NULL;
|
||||
if (amt_m) {
|
||||
@@ -120,6 +124,8 @@ static void destroy_material(struct material *material)
|
||||
glDeleteTextures(1, &material->color_map);
|
||||
if (material->specular_map)
|
||||
glDeleteTextures(1, &material->specular_map);
|
||||
if (material->light_map)
|
||||
glDeleteTextures(1, &material->light_map);
|
||||
if (material->normal_map)
|
||||
glDeleteTextures(1, &material->normal_map);
|
||||
}
|
||||
@@ -192,10 +198,13 @@ static void *buf_alloc(uint8_t **ptr, int size)
|
||||
|
||||
static void add_mesh(struct model *model, struct pol_mesh *m, int material_index, int material, struct RE_renderer *r)
|
||||
{
|
||||
bool has_light_map = m->light_uvs && model->materials[material].light_map;
|
||||
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_normal_map)
|
||||
stride += sizeof(struct vertex_tangent);
|
||||
if (has_bones)
|
||||
@@ -218,6 +227,10 @@ static void add_mesh(struct model *model, struct pol_mesh *m, int material_index
|
||||
glm_vec3_copy(vert->pos, v_common->pos);
|
||||
glm_vec3_copy(t->normals[j], v_common->normal);
|
||||
glm_vec2_copy(m->uvs[t->uv_index[j]], v_common->uv);
|
||||
if (has_light_map) {
|
||||
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_normal_map) {
|
||||
struct vertex_tangent *v_tangent = buf_alloc(&ptr, sizeof(struct vertex_tangent));
|
||||
glm_vec4_ucopy(tangent[j], v_tangent->tangent);
|
||||
@@ -265,6 +278,14 @@ static void add_mesh(struct model *model, struct pol_mesh *m, int material_index
|
||||
glEnableVertexAttribArray(r->vertex_uv);
|
||||
glVertexAttribPointer(r->vertex_uv, 2, GL_FLOAT, GL_FALSE, stride, base + offsetof(struct vertex_common, uv));
|
||||
base += sizeof(struct vertex_common);
|
||||
if (has_light_map) {
|
||||
glEnableVertexAttribArray(r->vertex_light_uv);
|
||||
glVertexAttribPointer(r->vertex_light_uv, 2, GL_FLOAT, GL_FALSE, stride, base + offsetof(struct vertex_light_uv, uv));
|
||||
base += sizeof(struct vertex_light_uv);
|
||||
} else {
|
||||
glDisableVertexAttribArray(r->vertex_light_uv);
|
||||
glVertexAttrib2f(r->vertex_light_uv, 0.0, 0.0);
|
||||
}
|
||||
if (has_normal_map) {
|
||||
glEnableVertexAttribArray(r->vertex_tangent);
|
||||
glVertexAttribPointer(r->vertex_tangent, 4, GL_FLOAT, GL_FALSE, stride, base + offsetof(struct vertex_tangent, tangent));
|
||||
|
||||
+17
-8
@@ -125,14 +125,20 @@ static void destroy_vertex(struct pol_vertex *v)
|
||||
free(v->weights);
|
||||
}
|
||||
|
||||
static void parse_triangle(struct buffer *r, int unknowns_length, struct pol_triangle *t)
|
||||
static void parse_triangle(struct buffer *r, struct pol_mesh *mesh, int triangle_index, int unknowns_length)
|
||||
{
|
||||
struct pol_triangle *t = &mesh->triangles[triangle_index];
|
||||
t->vert_index[0] = buffer_read_int32(r);
|
||||
t->vert_index[1] = buffer_read_int32(r);
|
||||
t->vert_index[2] = buffer_read_int32(r);
|
||||
t->uv_index[0] = buffer_read_int32(r);
|
||||
t->uv_index[1] = buffer_read_int32(r);
|
||||
t->uv_index[2] = buffer_read_int32(r);
|
||||
if (mesh->light_uvs) {
|
||||
t->light_uv_index[0] = buffer_read_int32(r) - mesh->nr_uvs;
|
||||
t->light_uv_index[1] = buffer_read_int32(r) - mesh->nr_uvs;
|
||||
t->light_uv_index[2] = buffer_read_int32(r) - mesh->nr_uvs;
|
||||
}
|
||||
|
||||
buffer_skip(r, unknowns_length);
|
||||
|
||||
@@ -167,14 +173,16 @@ static struct pol_mesh *parse_mesh(struct buffer *r, int pol_version)
|
||||
mesh->uvs[i][1] = buffer_read_float(r);
|
||||
}
|
||||
|
||||
int triangle_unknowns_length = 12;
|
||||
|
||||
int nr_unknown_f64s = buffer_read_int32(r);
|
||||
if (nr_unknown_f64s) {
|
||||
buffer_skip(r, nr_unknown_f64s * 8);
|
||||
triangle_unknowns_length += 12;
|
||||
mesh->nr_light_uvs = buffer_read_int32(r);
|
||||
if (mesh->nr_light_uvs > 0) {
|
||||
mesh->light_uvs = xcalloc(mesh->nr_light_uvs, sizeof(vec2));
|
||||
for (uint32_t i = 0; i < mesh->nr_light_uvs; i++) {
|
||||
mesh->light_uvs[i][0] = buffer_read_float(r);
|
||||
mesh->light_uvs[i][1] = buffer_read_float(r);
|
||||
}
|
||||
}
|
||||
|
||||
int triangle_unknowns_length = 12;
|
||||
if (pol_version == 1) {
|
||||
int nr_unknown_vecs = buffer_read_int32(r);
|
||||
buffer_skip(r, nr_unknown_vecs * 12);
|
||||
@@ -191,7 +199,7 @@ static struct pol_mesh *parse_mesh(struct buffer *r, int pol_version)
|
||||
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, triangle_unknowns_length, &mesh->triangles[i]);
|
||||
parse_triangle(r, mesh, i, triangle_unknowns_length);
|
||||
}
|
||||
|
||||
if (pol_version == 1) {
|
||||
@@ -213,6 +221,7 @@ static void free_mesh(struct pol_mesh *mesh)
|
||||
destroy_vertex(&mesh->vertices[i]);
|
||||
free(mesh->vertices);
|
||||
free(mesh->uvs);
|
||||
free(mesh->light_uvs);
|
||||
free(mesh->triangles);
|
||||
free(mesh);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
enum {
|
||||
COLOR_TEXTURE_UNIT,
|
||||
SPECULAR_TEXTURE_UNIT,
|
||||
LIGHT_TEXTURE_UNIT,
|
||||
NORMAL_TEXTURE_UNIT,
|
||||
};
|
||||
|
||||
@@ -51,6 +52,8 @@ static void init_billboard_mesh(struct RE_renderer *r)
|
||||
glVertexAttribPointer(r->shader.vertex, 3, GL_FLOAT, GL_FALSE, 20, (const void *)0);
|
||||
glEnableVertexAttribArray(r->vertex_uv);
|
||||
glVertexAttribPointer(r->vertex_uv, 2, GL_FLOAT, GL_FALSE, 20, (const void *)12);
|
||||
glDisableVertexAttribArray(r->vertex_light_uv);
|
||||
glVertexAttrib2f(r->vertex_light_uv, 0.0, 0.0);
|
||||
glDisableVertexAttribArray(r->vertex_normal);
|
||||
glVertexAttrib3f(r->vertex_normal, 0.0, 0.0, 1.0);
|
||||
glDisableVertexAttribArray(r->vertex_tangent);
|
||||
@@ -95,10 +98,13 @@ struct RE_renderer *RE_renderer_new(struct texture *texture)
|
||||
r->rim_exponent = glGetUniformLocation(r->shader.program, "rim_exponent");
|
||||
r->rim_color = glGetUniformLocation(r->shader.program, "rim_color");
|
||||
r->view_pos = glGetUniformLocation(r->shader.program, "view_pos");
|
||||
r->use_light_map = glGetUniformLocation(r->shader.program, "use_light_map");
|
||||
r->light_texture = glGetUniformLocation(r->shader.program, "light_texture");
|
||||
r->use_normal_map = glGetUniformLocation(r->shader.program, "use_normal_map");
|
||||
r->normal_texture = glGetUniformLocation(r->shader.program, "normal_texture");
|
||||
r->vertex_normal = glGetAttribLocation(r->shader.program, "vertex_normal");
|
||||
r->vertex_uv = glGetAttribLocation(r->shader.program, "vertex_uv");
|
||||
r->vertex_light_uv = glGetAttribLocation(r->shader.program, "vertex_light_uv");
|
||||
r->vertex_tangent = glGetAttribLocation(r->shader.program, "vertex_tangent");
|
||||
r->vertex_bone_index = glGetAttribLocation(r->shader.program, "vertex_bone_index");
|
||||
r->vertex_bone_weight = glGetAttribLocation(r->shader.program, "vertex_bone_weight");
|
||||
@@ -304,6 +310,15 @@ static void render_model(struct RE_instance *inst, struct RE_renderer *r)
|
||||
glBindTexture(GL_TEXTURE_2D, material->color_map);
|
||||
glUniform1i(r->shader.texture, COLOR_TEXTURE_UNIT);
|
||||
|
||||
if (material->light_map && inst->plugin->light_map_mode) {
|
||||
glUniform1i(r->use_light_map, GL_TRUE);
|
||||
glActiveTexture(GL_TEXTURE0 + LIGHT_TEXTURE_UNIT);
|
||||
glBindTexture(GL_TEXTURE_2D, material->light_map);
|
||||
glUniform1i(r->light_texture, LIGHT_TEXTURE_UNIT);
|
||||
} else {
|
||||
glUniform1i(r->use_light_map, GL_FALSE);
|
||||
}
|
||||
|
||||
if (material->normal_map && inst->draw_bump && inst->plugin->bump_mode) {
|
||||
glUniform1i(r->use_normal_map, GL_TRUE);
|
||||
glActiveTexture(GL_TEXTURE0 + NORMAL_TEXTURE_UNIT);
|
||||
@@ -373,6 +388,7 @@ static void render_billboard(struct RE_instance *inst, struct RE_renderer *r, ma
|
||||
glUniform1f(r->specular_shininess, 0.0);
|
||||
glUniform1i(r->use_specular_map, GL_FALSE);
|
||||
glUniform1f(r->rim_exponent, 0.0);
|
||||
glUniform1i(r->use_light_map, GL_FALSE);
|
||||
glUniform1i(r->use_normal_map, GL_FALSE);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
Reference in New Issue
Block a user