Merge pull request #63 from kichikuou/lighting

ReignEngine: Implement bump mapping and light mapping
This commit is contained in:
Nunuhara Cabbage
2022-07-16 11:15:01 -07:00
committed by GitHub
9 changed files with 316 additions and 58 deletions
+1
View File
@@ -109,6 +109,7 @@ struct RE_instance {
vec3 scale;
float alpha;
bool draw;
bool draw_bump;
float fps;
bool motion_blend;
float motion_blend_rate;
+27 -9
View File
@@ -24,40 +24,57 @@ struct dir_light {
uniform sampler2D tex;
uniform sampler2D specular_texture;
uniform sampler2D light_texture;
uniform float alpha_mod;
uniform bool use_normal_map;
uniform sampler2D normal_texture;
uniform vec3 ambient;
uniform dir_light dir_lights[NR_DIR_LIGHTS];
uniform vec3 specular_light_dir;
uniform float specular_strength;
uniform float specular_shininess;
uniform bool use_specular_map;
uniform float rim_exponent;
uniform vec3 rim_color;
uniform vec3 view_pos;
uniform bool use_light_map;
in vec2 tex_coord;
in vec3 normal;
in vec2 light_tex_coord;
in vec3 frag_pos;
in vec3 eye;
in vec3 normal;
in vec3 light_dir[NR_DIR_LIGHTS];
in vec3 specular_dir;
out vec4 frag_color;
void main() {
vec3 norm = normalize(normal);
vec3 view_dir = normalize(view_pos - frag_pos);
vec3 norm;
if (use_normal_map) {
// NOTE: TT3's shader doesn't normalize this vector.
norm = texture(normal_texture, tex_coord).rgb * 2.0 - 1.0;
} else {
norm = normalize(normal);
}
vec3 view_dir = normalize(eye - frag_pos);
vec3 frag_rgb = ambient;
// Diffuse lighting
vec3 diffuse = vec3(0.0);
for (int i = 0; i < NR_DIR_LIGHTS; i++) {
float half_lambert = dot(norm, -dir_lights[i].dir) * 0.5 + 0.5;
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;
// Specular lighting
if (specular_strength > 0.0) {
vec3 reflect_dir = reflect(specular_light_dir, norm);
vec3 reflect_dir = reflect(specular_dir, norm);
float specular = pow(max(dot(view_dir, reflect_dir), 0.0), specular_shininess) * specular_strength;
if (use_specular_map) {
specular *= texture(specular_texture, tex_coord).r;
@@ -66,8 +83,9 @@ void main() {
}
// Rim lighting
if (rim_exponent > 0) {
frag_rgb += pow(1.0 - max(dot(norm, view_dir), 0.0), rim_exponent) * rim_color;
if (rim_exponent > 0.0) {
// Normal map is not used here.
frag_rgb += pow(1.0 - max(dot(normalize(normal), view_dir), 0.0), rim_exponent) * rim_color;
}
frag_color = vec4(frag_rgb, texel.a * alpha_mod);
+49 -6
View File
@@ -14,6 +14,14 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#define NR_DIR_LIGHTS 3
struct dir_light {
vec3 dir;
vec3 diffuse;
vec3 globe_diffuse;
};
uniform mat4 local_transform;
uniform mat4 view_transform;
uniform mat4 proj_transform;
@@ -24,31 +32,66 @@ const int NR_WEIGHTS = 4;
uniform bool has_bones;
uniform mat4 bone_matrices[MAX_BONES];
uniform bool use_normal_map;
uniform vec3 view_pos;
uniform dir_light dir_lights[NR_DIR_LIGHTS];
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 vec3 normal;
out vec2 light_tex_coord;
out vec3 frag_pos;
out vec3 eye;
out vec3 normal;
out vec3 light_dir[NR_DIR_LIGHTS];
out vec3 specular_dir;
void main() {
mat4 bone_transform = mat4(1.0f);
mat4 local_bone_transform = local_transform;
mat3 normal_bone_transform = normal_transform;
if (has_bones) {
bone_transform = mat4(0.f);
mat4 bone_transform = mat4(0.f);
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;
normal_bone_transform *= mat3(bone_transform);
}
vec4 world_pos = local_transform * bone_transform * vec4(vertex_pos, 1.0);
// World-space normal vector.
normal = normal_bone_transform * vertex_normal;
mat3 TBN = mat3(1.0f);
if (use_normal_map) {
vec3 tangent = normal_bone_transform * vertex_tangent.xyz;
vec3 bitangent = cross(normal, tangent) * vertex_tangent.w;
TBN = transpose(mat3(tangent, bitangent, normal));
// Tangent-space normal vector.
normal = vec3(0.0, 0.0, 1.0);
}
vec4 world_pos = local_bone_transform * vec4(vertex_pos, 1.0);
gl_Position = proj_transform * view_transform * world_pos;
normal = normal_transform * mat3(bone_transform) * vertex_normal;
tex_coord = vertex_uv;
frag_pos = vec3(world_pos);
light_tex_coord = vertex_light_uv;
// These are in tangent-space if use_normal_map is true, in world-space
// otherwise.
frag_pos = TBN * vec3(world_pos);
eye = TBN * view_pos;
light_dir[0] = TBN * dir_lights[0].dir;
light_dir[1] = TBN * dir_lights[1].dir;
light_dir[2] = TBN * dir_lights[2].dir;
specular_dir = TBN * specular_light_dir;
}
+13
View File
@@ -48,6 +48,8 @@ struct mesh {
struct material {
GLuint color_map;
GLuint specular_map;
GLuint light_map;
GLuint normal_map;
float specular_strength;
float specular_shininess;
float rim_exponent;
@@ -97,10 +99,16 @@ 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;
@@ -144,6 +152,8 @@ struct pol {
enum pol_texture_type {
COLOR_MAP = 1,
SPECULAR_MAP = 4,
LIGHT_MAP = 7,
NORMAL_MAP = 8,
MAX_TEXTURE_TYPE
};
@@ -165,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;
};
@@ -183,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
};
+157 -32
View File
@@ -14,6 +14,7 @@
* along with this program; if not, see <http://gnu.org/licenses/>.
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <cglm/cglm.h>
@@ -28,10 +29,21 @@
#define NR_WEIGHTS 4
struct vertex {
struct vertex_common {
GLfloat pos[3];
GLfloat normal[3];
GLfloat uv[2];
};
struct vertex_light_uv {
GLfloat uv[2];
};
struct vertex_tangent {
GLfloat tangent[4];
};
struct vertex_bones {
GLint bone_id[NR_WEIGHTS];
GLfloat bone_weight[NR_WEIGHTS];
};
@@ -84,9 +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[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) {
@@ -109,6 +124,10 @@ 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);
}
static int cmp_by_bone_weight(const void *lhs, const void *rhs)
@@ -130,65 +149,171 @@ static void sort_and_normalize_bone_weights(struct pol_vertex *v)
}
}
static void calc_tangent(struct pol_mesh *m, struct pol_triangle *t, vec4 tangent[3])
{
vec3 v1, v2;
glm_vec3_sub(m->vertices[t->vert_index[1]].pos, m->vertices[t->vert_index[0]].pos, v1);
glm_vec3_sub(m->vertices[t->vert_index[2]].pos, m->vertices[t->vert_index[0]].pos, v2);
vec2 w1, w2;
glm_vec2_sub(m->uvs[t->uv_index[1]], m->uvs[t->uv_index[0]], w1);
glm_vec2_sub(m->uvs[t->uv_index[2]], m->uvs[t->uv_index[0]], w2);
float r = 1.0 / (w1[0] * w2[1] - w2[0] * w1[1]);
if (!isfinite(r)) // degenerate uv triangle
r = 1.0; // ??
vec3 sdir, tdir;
glm_vec3_scale(v1, w2[1], sdir);
glm_vec3_muladds(v2, -w1[1], sdir);
glm_vec3_scale(sdir, r, sdir);
glm_vec3_scale(v2, w1[0], tdir);
glm_vec3_muladds(v1, -w2[0], tdir);
glm_vec3_scale(tdir, r, tdir);
for (int i = 0; i < 3; i++) {
vec3 s;
glm_vec3_copy(sdir, s);
// Gram-Schmidt orthogonalize.
glm_vec3_muladds(t->normals[i], -glm_vec3_dot(t->normals[i], s), s);
glm_vec3_normalize(s);
// Calculate handedness.
vec3 c;
glm_vec3_cross(t->normals[i], sdir, c);
float w = (glm_vec3_dot(c, tdir) < 0.0) ? -1.0 : 1.0;
glm_vec4(s, w, tangent[i]);
}
}
static void *buf_alloc(uint8_t **ptr, int size)
{
void *p = *ptr;
*ptr += size;
return p;
}
static void add_mesh(struct model *model, struct pol_mesh *m, int material_index, int material, struct RE_renderer *r)
{
struct vertex *buf = xmalloc(m->nr_triangles * 3 * sizeof(struct vertex));
int v = 0;
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)
stride += sizeof(struct vertex_bones);
void *buffer = xmalloc(m->nr_triangles * 3 * stride);
uint8_t *ptr = buffer;
int nr_vertices = 0;
for (uint32_t i = 0; i < m->nr_triangles; i++) {
struct pol_triangle *t = &m->triangles[i];
if (material_index >= 0 && t->material != (uint32_t)material_index)
continue;
vec4 tangent[3];
if (has_normal_map)
calc_tangent(m, t, tangent);
for (int j = 0; j < 3; j++) {
struct pol_vertex *vert = &m->vertices[t->vert_index[j]];
glm_vec3_copy(vert->pos, buf[v].pos);
glm_vec3_copy(t->normals[j], buf[v].normal);
glm_vec2_copy(m->uvs[t->uv_index[j]], buf[v].uv);
sort_and_normalize_bone_weights(vert);
for (uint32_t k = 0; k < NR_WEIGHTS; k++) {
if (model->bone_map && k < vert->nr_weights) {
struct bone *bone = ht_get_int(model->bone_map, vert->weights[k].bone, NULL);
if (!bone)
WARNING("%s: invalid bone id in vertex data", model->path);
buf[v].bone_id[k] = bone ? bone->index : -1;
buf[v].bone_weight[k] = vert->weights[k].weight;
} else {
buf[v].bone_id[k] = -1;
buf[v].bone_weight[k] = 0.0;
struct vertex_common *v_common = buf_alloc(&ptr, sizeof(struct vertex_common));
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);
}
if (has_bones) {
struct vertex_bones *v_bones = buf_alloc(&ptr, sizeof(struct vertex_bones));
sort_and_normalize_bone_weights(vert);
for (uint32_t k = 0; k < NR_WEIGHTS; k++) {
if (k < vert->nr_weights) {
struct bone *bone = ht_get_int(model->bone_map, vert->weights[k].bone, NULL);
if (!bone)
WARNING("%s: invalid bone id in vertex data", model->path);
v_bones->bone_id[k] = bone ? bone->index : -1;
v_bones->bone_weight[k] = vert->weights[k].weight;
} else {
v_bones->bone_id[k] = -1;
v_bones->bone_weight[k] = 0.0;
}
}
}
v++;
nr_vertices++;
}
}
if (v == 0) {
free(buf);
assert(ptr == (uint8_t *)buffer + nr_vertices * stride);
if (nr_vertices == 0) {
free(buffer);
return;
}
model->meshes = xrealloc_array(model->meshes, model->nr_meshes, model->nr_meshes + 1, sizeof(struct mesh));
struct mesh *mesh = &model->meshes[model->nr_meshes++];
mesh->material = material;
mesh->nr_vertices = v;
mesh->nr_vertices = nr_vertices;
glGenVertexArrays(1, &mesh->vao);
glBindVertexArray(mesh->vao);
glGenBuffers(1, &mesh->attr_buffer);
glBindBuffer(GL_ARRAY_BUFFER, mesh->attr_buffer);
const uint8_t *base = (const uint8_t *)0;
glEnableVertexAttribArray(r->shader.vertex);
glVertexAttribPointer(r->shader.vertex, 3, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (const void *)0);
glVertexAttribPointer(r->shader.vertex, 3, GL_FLOAT, GL_FALSE, stride, base + offsetof(struct vertex_common, pos));
glEnableVertexAttribArray(r->vertex_normal);
glVertexAttribPointer(r->vertex_normal, 3, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (const void *)offsetof(struct vertex, normal));
glVertexAttribPointer(r->vertex_normal, 3, GL_FLOAT, GL_FALSE, stride, base + offsetof(struct vertex_common, normal));
glEnableVertexAttribArray(r->vertex_uv);
glVertexAttribPointer(r->vertex_uv, 2, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (const void *)offsetof(struct vertex, uv));
glEnableVertexAttribArray(r->vertex_bone_index);
glVertexAttribIPointer(r->vertex_bone_index, NR_WEIGHTS, GL_INT, sizeof(struct vertex), (const void *)offsetof(struct vertex, bone_id));
glEnableVertexAttribArray(r->vertex_bone_weight);
glVertexAttribPointer(r->vertex_bone_weight, NR_WEIGHTS, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (const void *)offsetof(struct vertex, bone_weight));
glBufferData(GL_ARRAY_BUFFER, mesh->nr_vertices * sizeof(struct vertex), buf, GL_STATIC_DRAW);
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));
base += sizeof(struct vertex_tangent);
} else {
glDisableVertexAttribArray(r->vertex_tangent);
glVertexAttrib3f(r->vertex_tangent, 1.0, 0.0, 0.0);
}
if (has_bones) {
glEnableVertexAttribArray(r->vertex_bone_index);
glVertexAttribIPointer(r->vertex_bone_index, NR_WEIGHTS, GL_INT, stride, base + offsetof(struct vertex_bones, bone_id));
glEnableVertexAttribArray(r->vertex_bone_weight);
glVertexAttribPointer(r->vertex_bone_weight, NR_WEIGHTS, GL_FLOAT, GL_FALSE, stride, base + offsetof(struct vertex_bones, bone_weight));
base += sizeof(struct vertex_bones);
} else {
glDisableVertexAttribArray(r->vertex_bone_index);
glVertexAttribI4i(r->vertex_bone_index, 0, 0, 0, 0);
glDisableVertexAttribArray(r->vertex_bone_weight);
glVertexAttrib4f(r->vertex_bone_weight, 0.0, 0.0, 0.0, 0.0);
}
assert((intptr_t)base == stride);
glBufferData(GL_ARRAY_BUFFER, mesh->nr_vertices * stride, buffer, GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
free(buf);
free(buffer);
}
static void destroy_mesh(struct mesh *mesh)
+17 -8
View File
@@ -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);
}
+1
View File
@@ -40,6 +40,7 @@ static struct RE_instance *create_instance(struct RE_plugin *plugin)
instance->scale[1] = 1.0;
instance->scale[2] = 1.0;
instance->alpha = 1.0;
instance->draw_bump = true;
instance->fps = 30.0;
glm_mat4_identity(instance->local_transform);
glm_mat3_identity(instance->normal_transform);
+32
View File
@@ -30,6 +30,8 @@
enum {
COLOR_TEXTURE_UNIT,
SPECULAR_TEXTURE_UNIT,
LIGHT_TEXTURE_UNIT,
NORMAL_TEXTURE_UNIT,
};
static void init_billboard_mesh(struct RE_renderer *r)
@@ -50,8 +52,12 @@ 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);
glVertexAttrib3f(r->vertex_tangent, 1.0, 0.0, 0.0);
glDisableVertexAttribArray(r->vertex_bone_index);
glVertexAttribI4i(r->vertex_bone_index, 0, 0, 0, 0);
glDisableVertexAttribArray(r->vertex_bone_weight);
@@ -92,8 +98,14 @@ 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");
@@ -298,6 +310,24 @@ 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);
glBindTexture(GL_TEXTURE_2D, material->normal_map);
glUniform1i(r->normal_texture, NORMAL_TEXTURE_UNIT);
} else {
glUniform1i(r->use_normal_map, GL_FALSE);
}
glBindVertexArray(mesh->vao);
glDrawArrays(GL_TRIANGLES, 0, mesh->nr_vertices);
glBindVertexArray(0);
@@ -358,6 +388,8 @@ 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);
glBindTexture(GL_TEXTURE_2D, bt->texture);
+19 -3
View File
@@ -285,7 +285,15 @@ static bool ReignEngine_SetInstanceDraw(int plugin, int instance, bool flag)
HLL_WARN_UNIMPLEMENTED(false, bool, ReignEngine, SetInstanceDrawShadow, int plugin, int instance, bool flag);
HLL_WARN_UNIMPLEMENTED(false, bool, ReignEngine, SetInstanceDrawBackShadow, int plugin, int instance, bool flag);
HLL_WARN_UNIMPLEMENTED(false, bool, ReignEngine, SetInstanceDrawMakeShadow, int plugin, int instance, bool flag);
HLL_WARN_UNIMPLEMENTED(false, bool, ReignEngine, SetInstanceDrawBump, int plugin, int instance, bool flag);
static bool ReignEngine_SetInstanceDrawBump(int plugin, int instance, bool flag)
{
struct RE_instance *ri = get_instance(plugin, instance);
if (!ri)
return false;
ri->draw_bump = flag;
return true;
}
static bool ReignEngine_GetInstanceDraw(int plugin, int instance)
{
@@ -298,7 +306,15 @@ static bool ReignEngine_GetInstanceDraw(int plugin, int instance)
//bool ReignEngine_GetInstanceDrawShadow(int plugin, int instance);
//bool ReignEngine_GetInstanceDrawBackShadow(int plugin, int instance);
//bool ReignEngine_GetInstanceDrawMakeShadow(int plugin, int instance);
//bool ReignEngine_GetInstanceDrawBump(int plugin, int instance);
static bool ReignEngine_GetInstanceDrawBump(int plugin, int instance)
{
struct RE_instance *ri = get_instance(plugin, instance);
if (!ri)
return false;
return ri->draw_bump;
}
//int ReignEngine_GetInstanceDrawType(int plugin, int instance);
HLL_WARN_UNIMPLEMENTED(false, bool, ReignEngine, SetInstanceDrawType, int plugin, int instance, int draw_type);
@@ -1164,7 +1180,7 @@ HLL_LIBRARY(ReignEngine,
HLL_TODO_EXPORT(GetInstanceDrawShadow, ReignEngine_GetInstanceDrawShadow),
HLL_TODO_EXPORT(GetInstanceDrawBackShadow, ReignEngine_GetInstanceDrawBackShadow),
HLL_TODO_EXPORT(GetInstanceDrawMakeShadow, ReignEngine_GetInstanceDrawMakeShadow),
HLL_TODO_EXPORT(GetInstanceDrawBump, ReignEngine_GetInstanceDrawBump),
HLL_EXPORT(GetInstanceDrawBump, ReignEngine_GetInstanceDrawBump),
HLL_TODO_EXPORT(GetInstanceDrawType, ReignEngine_GetInstanceDrawType),
HLL_EXPORT(SetInstanceDrawType, ReignEngine_SetInstanceDrawType),
HLL_EXPORT(LoadInstanceMotion, ReignEngine_LoadInstanceMotion),