mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-10 08:18:14 +03:00
Merge pull request #63 from kichikuou/lighting
ReignEngine: Implement bump mapping and light mapping
This commit is contained in:
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user