render: finish up phong shading
parent
b44fd791a6
commit
fff4880c4f
|
@ -41,7 +41,7 @@ int main() {
|
|||
|
||||
// create point light
|
||||
light_t* l = scene_spawn_light();
|
||||
light_type(l, LIGHT_POINT);
|
||||
light_type(l, LIGHT_SPOT);
|
||||
|
||||
while(window_swap() && !input(KEY_ESC)) {
|
||||
// draw environment
|
||||
|
@ -53,6 +53,7 @@ int main() {
|
|||
|
||||
// update light position
|
||||
light_teleport(l, cam.position);
|
||||
light_dir(l, cam.look);
|
||||
|
||||
// draw scene
|
||||
scene_render(SCENE_FOREGROUND|SCENE_BACKGROUND|SCENE_UPDATE_SH_COEF);
|
||||
|
|
|
@ -7,6 +7,7 @@ uniform bool u_matcaps = false;
|
|||
uniform vec4 u_diffuse = vec4(1.0,1.0,1.0,1.0);
|
||||
|
||||
in vec3 v_position;
|
||||
in vec3 v_position_ws;
|
||||
#ifdef RIM
|
||||
uniform mat4 M; // RIM
|
||||
uniform vec3 u_rimcolor = vec3(0.2,0.2,0.2);
|
||||
|
@ -28,14 +29,25 @@ vec4 shadowing() {
|
|||
return shadowmap(vpeye, vneye, v_texcoord, sc);
|
||||
}
|
||||
|
||||
uniform vec3 u_cam_pos;
|
||||
uniform vec3 u_cam_dir;
|
||||
|
||||
uniform int u_num_lights;
|
||||
|
||||
struct light_t {
|
||||
int type;
|
||||
vec3 color;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
vec3 ambient;
|
||||
vec3 pos;
|
||||
vec3 dir;
|
||||
float radius;
|
||||
float innerCone;
|
||||
float outerCone;
|
||||
|
||||
// falloff
|
||||
float constant;
|
||||
float linear;
|
||||
float quadratic;
|
||||
};
|
||||
|
||||
#define MAX_LIGHTS 16
|
||||
|
@ -45,27 +57,53 @@ const int LIGHT_SPOT = 2;
|
|||
|
||||
uniform light_t u_lights[MAX_LIGHTS];
|
||||
|
||||
vec3 calculate_light(light_t l, vec3 normal, vec3 fragPos, vec3 viewDir) {
|
||||
#ifdef SHADING_PHONG
|
||||
vec3 shading_phong(light_t l) {
|
||||
vec3 lightDir;
|
||||
float attenuation = 1.0;
|
||||
|
||||
if (l.type == LIGHT_DIRECTIONAL) {
|
||||
lightDir = normalize(-l.dir);
|
||||
} else if (l.type == LIGHT_POINT) {
|
||||
vec3 toLight = l.pos - fragPos;
|
||||
vec3 toLight = l.pos - v_position_ws;
|
||||
lightDir = normalize(toLight);
|
||||
float distance = length(toLight);
|
||||
float factor = distance / (l.radius*l.radius);
|
||||
attenuation = clamp(1.0 - factor, 0.0, 1.0);
|
||||
attenuation = 1.0 / (l.constant + l.linear * distance + l.quadratic * (distance * distance));
|
||||
} else if (l.type == LIGHT_SPOT) {
|
||||
vec3 toLight = l.pos - v_position_ws;
|
||||
lightDir = normalize(toLight);
|
||||
float distance = length(toLight);
|
||||
attenuation = 1.0 / (l.constant + l.linear * distance + l.quadratic * (distance * distance));
|
||||
|
||||
// Calculate spotlight effect
|
||||
float angle = dot(l.dir, normalize(-lightDir));
|
||||
if (angle > l.outerCone) {
|
||||
float intensity = (angle-l.outerCone)/(l.innerCone-l.outerCone);
|
||||
attenuation *= clamp(intensity, 0.0, 1.0);
|
||||
} else {
|
||||
attenuation = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
float diffuse = max(dot(v_normal, lightDir), 0.0);
|
||||
|
||||
// vec3 reflectDir = reflect(-lightDir, normal);
|
||||
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
|
||||
// vec3 specular = spec * lightColor;
|
||||
vec3 halfVec = normalize(lightDir + u_cam_dir);
|
||||
float specular = pow(max(dot(v_normal, halfVec), 0.0), 32);
|
||||
|
||||
return (diff /* + specular */) * l.color;
|
||||
return (attenuation*l.ambient + diffuse*attenuation*l.diffuse + specular*attenuation*l.specular);
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 lighting() {
|
||||
vec3 lit = vec3(0,0,0);
|
||||
#ifndef SHADING_NONE
|
||||
for (int i=0; i<u_num_lights; i++) {
|
||||
#ifdef SHADING_PHONG
|
||||
lit += shading_phong(u_lights[i]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return lit;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
@ -91,10 +129,7 @@ void main() {
|
|||
}
|
||||
|
||||
// analytical lights (phong shading)
|
||||
// @todo: support more shading models (blinn-phong, ue4 brdf, ...)
|
||||
for (int i=0; i<u_num_lights; i++) {
|
||||
lit += vec4(calculate_light(u_lights[i], n, v_position, /* @todo: push vdeye */ vec3(1.0,1.0,1.0)), 0.0);
|
||||
}
|
||||
lit += vec4(lighting(), 0.0);
|
||||
|
||||
// base
|
||||
vec4 diffuse;
|
||||
|
|
|
@ -57,7 +57,7 @@ in float att_vertexindex; // for blendshapes
|
|||
in vec4 att_color;
|
||||
in vec3 att_bitangent; // @todo: remove? also, ass2iqe might output this
|
||||
out vec4 v_color;
|
||||
out vec3 v_position;
|
||||
out vec3 v_position, v_position_ws;
|
||||
out vec3 v_normal, v_normal_ws;
|
||||
out vec2 v_texcoord;
|
||||
|
||||
|
@ -115,6 +115,7 @@ void main() {
|
|||
|
||||
v_normal_ws = normalize(vec3(model * vec4(v_normal, 0.))); // normal to world/model space
|
||||
v_normal = normalize(v_normal);
|
||||
v_position_ws = (att_instanced_matrix * vec4( objPos, 1.0 )).xyz;
|
||||
v_position = att_position;
|
||||
v_texcoord = att_texcoord;
|
||||
v_color = att_color;
|
||||
|
|
|
@ -6,11 +6,12 @@ in vec3 att_normal;
|
|||
in vec2 att_texcoord;
|
||||
in vec4 att_color;
|
||||
out vec4 v_color;
|
||||
out vec3 v_position;
|
||||
out vec3 v_position_ws;
|
||||
out vec3 v_normal;
|
||||
out vec3 v_normal_ws;
|
||||
out vec2 v_texcoord;
|
||||
|
||||
|
||||
// shadow
|
||||
uniform mat4 model, view, proj;
|
||||
uniform mat4 cameraToShadowProjector; // !VSMCUBE
|
||||
|
@ -26,6 +27,8 @@ void do_shadow() {
|
|||
|
||||
void main() {
|
||||
gl_Position = u_mvp * vec4(att_position, 1.0);
|
||||
v_position = att_position;
|
||||
v_position_ws = vec3(model * vec4(att_position, 1.));
|
||||
v_normal = normalize(att_normal);
|
||||
v_normal_ws = normalize(vec3(model * vec4(att_normal, 0.))); // normal world/model space
|
||||
v_texcoord = att_texcoord;
|
||||
|
|
|
@ -1392,11 +1392,17 @@ ffi.cdef([[
|
|||
//lcpp INF [0000] vec3: macro name but used as C declaration in:API void object_scale(object_t *obj, vec3 sca);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void object_scale(object_t *obj, vec3 sca);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in: void object_scale(object_t *obj, vec3 sca);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:vec3 color;
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:vec3 diffuse, specular, ambient;
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:vec3 pos, dir;
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:API void light_color(light_t* l, vec3 color);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void light_color(light_t* l, vec3 color);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in: void light_color(light_t* l, vec3 color);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:API void light_diffuse(light_t* l, vec3 color);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void light_diffuse(light_t* l, vec3 color);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in: void light_diffuse(light_t* l, vec3 color);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:API void light_specular(light_t* l, vec3 color);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void light_specular(light_t* l, vec3 color);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in: void light_specular(light_t* l, vec3 color);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:API void light_ambient(light_t* l, vec3 color);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void light_ambient(light_t* l, vec3 color);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in: void light_ambient(light_t* l, vec3 color);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:API void light_teleport(light_t* l, vec3 pos);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void light_teleport(light_t* l, vec3 pos);
|
||||
//lcpp INF [0000] vec3: macro name but used as C declaration in: void light_teleport(light_t* l, vec3 pos);
|
||||
|
@ -2695,17 +2701,23 @@ LIGHT_CAST_SHADOWS = 1,
|
|||
};
|
||||
typedef struct light_t {
|
||||
char type;
|
||||
vec3 color;
|
||||
vec3 diffuse, specular, ambient;
|
||||
vec3 pos, dir;
|
||||
float radius;
|
||||
struct {
|
||||
float constant, linear, quadratic;
|
||||
} falloff;
|
||||
float innerCone, outerCone;
|
||||
bool cached;
|
||||
} light_t;
|
||||
light_t light();
|
||||
void light_type(light_t* l, char type);
|
||||
void light_color(light_t* l, vec3 color);
|
||||
void light_diffuse(light_t* l, vec3 color);
|
||||
void light_specular(light_t* l, vec3 color);
|
||||
void light_ambient(light_t* l, vec3 color);
|
||||
void light_teleport(light_t* l, vec3 pos);
|
||||
void light_dir(light_t* l, vec3 dir);
|
||||
void light_radius(light_t* l, float radius);
|
||||
void light_falloff(light_t* l, float constant, float linear, float quadratic);
|
||||
void light_cone(light_t* l, float innerCone, float outerCone);
|
||||
void light_update(unsigned num_lights, light_t *lv);
|
||||
enum SCENE_FLAGS {
|
||||
SCENE_WIREFRAME = 1,
|
||||
|
@ -2715,7 +2727,6 @@ SCENE_FOREGROUND = 8,
|
|||
SCENE_UPDATE_SH_COEF = 16,
|
||||
};
|
||||
typedef struct scene_t {
|
||||
handle program;
|
||||
object_t* objs;
|
||||
light_t* lights;
|
||||
skybox_t skybox;
|
||||
|
|
|
@ -16922,6 +16922,14 @@ enum MODEL_FLAGS {
|
|||
MODEL_RIMLIGHT = 16
|
||||
};
|
||||
|
||||
//@todo: make this data-driven
|
||||
// enum SHADING_MODE {
|
||||
// SHADING_NONE,
|
||||
// SHADING_PHONG,
|
||||
// SHADING_CARTOON,
|
||||
// // SHADING_PBR,
|
||||
// };
|
||||
|
||||
typedef struct model_t {
|
||||
struct iqm_t *iqm; // private
|
||||
|
||||
|
@ -17164,21 +17172,28 @@ enum LIGHT_FLAGS {
|
|||
|
||||
typedef struct light_t {
|
||||
char type;
|
||||
vec3 color;
|
||||
vec3 diffuse, specular, ambient;
|
||||
vec3 pos, dir;
|
||||
float radius;
|
||||
struct {
|
||||
float constant, linear, quadratic;
|
||||
} falloff;
|
||||
float innerCone, outerCone;
|
||||
//@todo: cookie, flare
|
||||
|
||||
// internals
|
||||
bool cached; //< used by scene to invalidate cached light data
|
||||
//@todo: inner/outer cone, flags, cookie, flare
|
||||
} light_t;
|
||||
|
||||
API light_t light();
|
||||
// API void light_flags(int flags);
|
||||
API void light_type(light_t* l, char type);
|
||||
API void light_color(light_t* l, vec3 color);
|
||||
API void light_diffuse(light_t* l, vec3 color);
|
||||
API void light_specular(light_t* l, vec3 color);
|
||||
API void light_ambient(light_t* l, vec3 color);
|
||||
API void light_teleport(light_t* l, vec3 pos);
|
||||
API void light_dir(light_t* l, vec3 dir);
|
||||
API void light_radius(light_t* l, float radius);
|
||||
// API void light_cone(light_t* l, float inner, float outer);
|
||||
API void light_falloff(light_t* l, float constant, float linear, float quadratic);
|
||||
API void light_cone(light_t* l, float innerCone, float outerCone);
|
||||
API void light_update(unsigned num_lights, light_t *lv);
|
||||
|
||||
// scene
|
||||
|
@ -17192,8 +17207,6 @@ enum SCENE_FLAGS {
|
|||
};
|
||||
|
||||
typedef struct scene_t {
|
||||
handle program;
|
||||
|
||||
array(object_t) objs;
|
||||
array(light_t) lights;
|
||||
|
||||
|
@ -343293,6 +343306,24 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
|
|||
mat44 vp; multiply44x2(vp, proj, view);
|
||||
glUniformMatrix4fv( loc, 1, GL_FALSE, vp);
|
||||
}
|
||||
if( (loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0 ) {
|
||||
vec3 pos = vec3(view[3], view[6], view[9]);
|
||||
glUniform3fv( loc, 1, &pos.x );
|
||||
}
|
||||
else
|
||||
if( (loc = glGetUniformLocation(shader, "cam_pos")) >= 0 ) {
|
||||
vec3 pos = vec3(view[3], view[6], view[9]);
|
||||
glUniform3fv( loc, 1, &pos.x );
|
||||
}
|
||||
if( (loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0 ) {
|
||||
vec3 dir = vec3(view[0], view[1], view[2]);
|
||||
glUniform3fv( loc, 1, &dir.x );
|
||||
}
|
||||
else
|
||||
if( (loc = glGetUniformLocation(shader, "cam_dir")) >= 0 ) {
|
||||
vec3 dir = vec3(view[0], view[1], view[2]);
|
||||
glUniform3fv( loc, 1, &dir.x );
|
||||
}
|
||||
#if 0
|
||||
// @todo: mat44 projview (useful?)
|
||||
#endif
|
||||
|
@ -343729,13 +343760,14 @@ model_t model_from_mem(const void *mem, int len, int flags) {
|
|||
model_t m = {0};
|
||||
|
||||
const char *ptr = (const char *)mem;
|
||||
static int shaderprog = -1;
|
||||
if( shaderprog < 0 ) {
|
||||
// can't cache shader programs since we enable features via flags here
|
||||
// static int shaderprog = -1;
|
||||
// if( shaderprog < 0 ) {
|
||||
const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") }; // #define RIM
|
||||
shaderprog = shader(strlerp(1,symbols,vfs_read("shaders/vs_323444143_16_332_model.glsl")), strlerp(1,symbols,vfs_read("shaders/fs_32_4_model.glsl")), //fs,
|
||||
int shaderprog = shader(strlerp(1,symbols,vfs_read("shaders/vs_323444143_16_332_model.glsl")), strlerp(1,symbols,vfs_read("shaders/fs_32_4_model.glsl")), //fs,
|
||||
"att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor",
|
||||
(flags&MODEL_RIMLIGHT)?"RIM":NULL);
|
||||
}
|
||||
va("SHADING_PHONG,%s", (flags&MODEL_RIMLIGHT)?"RIM":""));
|
||||
// }
|
||||
|
||||
iqm_t *q = CALLOC(1, sizeof(iqm_t));
|
||||
program = shaderprog;
|
||||
|
@ -345198,9 +345230,13 @@ void object_billboard(object_t *obj, unsigned mode) {
|
|||
|
||||
light_t light() {
|
||||
light_t l = {0};
|
||||
l.color = vec3(1,1,1);
|
||||
l.radius = 2.5f;
|
||||
l.diffuse = vec3(1,1,1);
|
||||
l.dir = vec3(1,-1,-1);
|
||||
l.falloff.constant = 1.0f;
|
||||
l.falloff.linear = 0.09f;
|
||||
l.falloff.quadratic = 0.0032f;
|
||||
l.innerCone = 0.9f; // 25 deg
|
||||
l.outerCone = 0.85f; // 31 deg
|
||||
|
||||
return l;
|
||||
}
|
||||
|
@ -345210,9 +345246,19 @@ void light_type(light_t* l, char type) {
|
|||
l->type = type;
|
||||
}
|
||||
|
||||
void light_color(light_t* l, vec3 color) {
|
||||
void light_diffuse(light_t* l, vec3 color) {
|
||||
l->cached = 0;
|
||||
l->color = color;
|
||||
l->diffuse = color;
|
||||
}
|
||||
|
||||
void light_specular(light_t* l, vec3 color) {
|
||||
l->cached = 0;
|
||||
l->specular = color;
|
||||
}
|
||||
|
||||
void light_ambient(light_t* l, vec3 color) {
|
||||
l->cached = 0;
|
||||
l->ambient = color;
|
||||
}
|
||||
|
||||
void light_teleport(light_t* l, vec3 pos) {
|
||||
|
@ -345225,9 +345271,16 @@ void light_dir(light_t* l, vec3 dir) {
|
|||
l->dir = dir;
|
||||
}
|
||||
|
||||
void light_radius(light_t* l, float radius) {
|
||||
void light_falloff(light_t* l, float constant, float linear, float quadratic) {
|
||||
l->cached = 0;
|
||||
l->radius = radius;
|
||||
l->falloff.constant = constant;
|
||||
l->falloff.linear = linear;
|
||||
l->falloff.quadratic = quadratic;
|
||||
}
|
||||
|
||||
void light_cone(light_t* l, float innerCone, float outerCone) {
|
||||
l->innerCone = acos(innerCone);
|
||||
l->outerCone = acos(outerCone);
|
||||
}
|
||||
|
||||
void light_update(unsigned num_lights, light_t *lv) {
|
||||
|
@ -345236,9 +345289,16 @@ void light_update(unsigned num_lights, light_t *lv) {
|
|||
for (unsigned i=0; i < num_lights; ++i) {
|
||||
lv[i].cached = 1;
|
||||
shader_int(va("u_lights[%d].type", i), lv[i].type);
|
||||
shader_vec3(va("u_lights[%d].color", i), lv[i].color);
|
||||
shader_vec3(va("u_lights[%d].pos", i), lv[i].pos);
|
||||
shader_vec3(va("u_lights[%d].dir", i), lv[i].dir);
|
||||
shader_vec3(va("u_lights[%d].diffuse", i), lv[i].diffuse);
|
||||
shader_vec3(va("u_lights[%d].specular", i), lv[i].specular);
|
||||
shader_vec3(va("u_lights[%d].ambient", i), lv[i].ambient);
|
||||
shader_float(va("u_lights[%d].constant", i), lv[i].falloff.constant);
|
||||
shader_float(va("u_lights[%d].linear", i), lv[i].falloff.linear);
|
||||
shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic);
|
||||
shader_float(va("u_lights[%d].innerCone", i), lv[i].innerCone);
|
||||
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345259,8 +345319,6 @@ scene_t* scene_get_active() {
|
|||
|
||||
scene_t* scene_push() {
|
||||
scene_t *s = REALLOC(0, sizeof(scene_t)), clear = {0}; *s = clear;
|
||||
const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") };
|
||||
s->program = shader(strlerp(1, symbols, vfs_read("shaders/vs_332_32.glsl")), strlerp(1, symbols, vfs_read("shaders/fs_32_4_model.glsl")), "att_position,att_normal,att_texcoord,att_color", "fragcolor", NULL);
|
||||
s->skybox = skybox(NULL, 0);
|
||||
array_push(scenes, s);
|
||||
last_scene = s;
|
||||
|
@ -345371,7 +345429,6 @@ void scene_render(int flags) {
|
|||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glUseProgram(last_scene->program);
|
||||
|
||||
if(flags & SCENE_BACKGROUND) {
|
||||
if(last_scene->skybox.program) {
|
||||
|
@ -345392,7 +345449,6 @@ void scene_render(int flags) {
|
|||
|
||||
glDepthFunc(GL_LESS);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
// glUseProgram(last_scene->program);
|
||||
|
||||
// @fixme: CW ok for one-sided rendering. CCW ok for FXs. we need both
|
||||
(flags & SCENE_CULLFACE ? glEnable : glDisable)(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace(GL_CCW);
|
||||
|
|
|
@ -3683,6 +3683,24 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
|
|||
mat44 vp; multiply44x2(vp, proj, view);
|
||||
glUniformMatrix4fv( loc, 1, GL_FALSE, vp);
|
||||
}
|
||||
if( (loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0 ) {
|
||||
vec3 pos = vec3(view[3], view[6], view[9]);
|
||||
glUniform3fv( loc, 1, &pos.x );
|
||||
}
|
||||
else
|
||||
if( (loc = glGetUniformLocation(shader, "cam_pos")) >= 0 ) {
|
||||
vec3 pos = vec3(view[3], view[6], view[9]);
|
||||
glUniform3fv( loc, 1, &pos.x );
|
||||
}
|
||||
if( (loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0 ) {
|
||||
vec3 dir = vec3(view[0], view[1], view[2]);
|
||||
glUniform3fv( loc, 1, &dir.x );
|
||||
}
|
||||
else
|
||||
if( (loc = glGetUniformLocation(shader, "cam_dir")) >= 0 ) {
|
||||
vec3 dir = vec3(view[0], view[1], view[2]);
|
||||
glUniform3fv( loc, 1, &dir.x );
|
||||
}
|
||||
#if 0
|
||||
// @todo: mat44 projview (useful?)
|
||||
#endif
|
||||
|
@ -4119,13 +4137,14 @@ model_t model_from_mem(const void *mem, int len, int flags) {
|
|||
model_t m = {0};
|
||||
|
||||
const char *ptr = (const char *)mem;
|
||||
static int shaderprog = -1;
|
||||
if( shaderprog < 0 ) {
|
||||
// can't cache shader programs since we enable features via flags here
|
||||
// static int shaderprog = -1;
|
||||
// if( shaderprog < 0 ) {
|
||||
const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") }; // #define RIM
|
||||
shaderprog = shader(strlerp(1,symbols,vfs_read("shaders/vs_323444143_16_332_model.glsl")), strlerp(1,symbols,vfs_read("shaders/fs_32_4_model.glsl")), //fs,
|
||||
int shaderprog = shader(strlerp(1,symbols,vfs_read("shaders/vs_323444143_16_332_model.glsl")), strlerp(1,symbols,vfs_read("shaders/fs_32_4_model.glsl")), //fs,
|
||||
"att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor",
|
||||
(flags&MODEL_RIMLIGHT)?"RIM":NULL);
|
||||
}
|
||||
va("SHADING_PHONG,%s", (flags&MODEL_RIMLIGHT)?"RIM":""));
|
||||
// }
|
||||
|
||||
iqm_t *q = CALLOC(1, sizeof(iqm_t));
|
||||
program = shaderprog;
|
||||
|
|
|
@ -572,6 +572,14 @@ enum MODEL_FLAGS {
|
|||
MODEL_RIMLIGHT = 16
|
||||
};
|
||||
|
||||
//@todo: make this data-driven
|
||||
// enum SHADING_MODE {
|
||||
// SHADING_NONE,
|
||||
// SHADING_PHONG,
|
||||
// SHADING_CARTOON,
|
||||
// // SHADING_PBR,
|
||||
// };
|
||||
|
||||
typedef struct model_t {
|
||||
struct iqm_t *iqm; // private
|
||||
|
||||
|
|
|
@ -243,9 +243,13 @@ void object_billboard(object_t *obj, unsigned mode) {
|
|||
|
||||
light_t light() {
|
||||
light_t l = {0};
|
||||
l.color = vec3(1,1,1);
|
||||
l.radius = 2.5f;
|
||||
l.diffuse = vec3(1,1,1);
|
||||
l.dir = vec3(1,-1,-1);
|
||||
l.falloff.constant = 1.0f;
|
||||
l.falloff.linear = 0.09f;
|
||||
l.falloff.quadratic = 0.0032f;
|
||||
l.innerCone = 0.9f; // 25 deg
|
||||
l.outerCone = 0.85f; // 31 deg
|
||||
|
||||
return l;
|
||||
}
|
||||
|
@ -255,9 +259,19 @@ void light_type(light_t* l, char type) {
|
|||
l->type = type;
|
||||
}
|
||||
|
||||
void light_color(light_t* l, vec3 color) {
|
||||
void light_diffuse(light_t* l, vec3 color) {
|
||||
l->cached = 0;
|
||||
l->color = color;
|
||||
l->diffuse = color;
|
||||
}
|
||||
|
||||
void light_specular(light_t* l, vec3 color) {
|
||||
l->cached = 0;
|
||||
l->specular = color;
|
||||
}
|
||||
|
||||
void light_ambient(light_t* l, vec3 color) {
|
||||
l->cached = 0;
|
||||
l->ambient = color;
|
||||
}
|
||||
|
||||
void light_teleport(light_t* l, vec3 pos) {
|
||||
|
@ -270,9 +284,16 @@ void light_dir(light_t* l, vec3 dir) {
|
|||
l->dir = dir;
|
||||
}
|
||||
|
||||
void light_radius(light_t* l, float radius) {
|
||||
void light_falloff(light_t* l, float constant, float linear, float quadratic) {
|
||||
l->cached = 0;
|
||||
l->radius = radius;
|
||||
l->falloff.constant = constant;
|
||||
l->falloff.linear = linear;
|
||||
l->falloff.quadratic = quadratic;
|
||||
}
|
||||
|
||||
void light_cone(light_t* l, float innerCone, float outerCone) {
|
||||
l->innerCone = acos(innerCone);
|
||||
l->outerCone = acos(outerCone);
|
||||
}
|
||||
|
||||
void light_update(unsigned num_lights, light_t *lv) {
|
||||
|
@ -281,9 +302,16 @@ void light_update(unsigned num_lights, light_t *lv) {
|
|||
for (unsigned i=0; i < num_lights; ++i) {
|
||||
lv[i].cached = 1;
|
||||
shader_int(va("u_lights[%d].type", i), lv[i].type);
|
||||
shader_vec3(va("u_lights[%d].color", i), lv[i].color);
|
||||
shader_vec3(va("u_lights[%d].pos", i), lv[i].pos);
|
||||
shader_vec3(va("u_lights[%d].dir", i), lv[i].dir);
|
||||
shader_vec3(va("u_lights[%d].diffuse", i), lv[i].diffuse);
|
||||
shader_vec3(va("u_lights[%d].specular", i), lv[i].specular);
|
||||
shader_vec3(va("u_lights[%d].ambient", i), lv[i].ambient);
|
||||
shader_float(va("u_lights[%d].constant", i), lv[i].falloff.constant);
|
||||
shader_float(va("u_lights[%d].linear", i), lv[i].falloff.linear);
|
||||
shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic);
|
||||
shader_float(va("u_lights[%d].innerCone", i), lv[i].innerCone);
|
||||
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,8 +332,6 @@ scene_t* scene_get_active() {
|
|||
|
||||
scene_t* scene_push() {
|
||||
scene_t *s = REALLOC(0, sizeof(scene_t)), clear = {0}; *s = clear;
|
||||
const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") };
|
||||
s->program = shader(strlerp(1, symbols, vfs_read("shaders/vs_332_32.glsl")), strlerp(1, symbols, vfs_read("shaders/fs_32_4_model.glsl")), "att_position,att_normal,att_texcoord,att_color", "fragcolor", NULL);
|
||||
s->skybox = skybox(NULL, 0);
|
||||
array_push(scenes, s);
|
||||
last_scene = s;
|
||||
|
@ -416,7 +442,6 @@ void scene_render(int flags) {
|
|||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glUseProgram(last_scene->program);
|
||||
|
||||
if(flags & SCENE_BACKGROUND) {
|
||||
if(last_scene->skybox.program) {
|
||||
|
@ -437,7 +462,6 @@ void scene_render(int flags) {
|
|||
|
||||
glDepthFunc(GL_LESS);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
// glUseProgram(last_scene->program);
|
||||
|
||||
// @fixme: CW ok for one-sided rendering. CCW ok for FXs. we need both
|
||||
(flags & SCENE_CULLFACE ? glEnable : glDisable)(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace(GL_CCW);
|
||||
|
|
|
@ -66,21 +66,28 @@ enum LIGHT_FLAGS {
|
|||
|
||||
typedef struct light_t {
|
||||
char type;
|
||||
vec3 color;
|
||||
vec3 diffuse, specular, ambient;
|
||||
vec3 pos, dir;
|
||||
float radius;
|
||||
struct {
|
||||
float constant, linear, quadratic;
|
||||
} falloff;
|
||||
float innerCone, outerCone;
|
||||
//@todo: cookie, flare
|
||||
|
||||
// internals
|
||||
bool cached; //< used by scene to invalidate cached light data
|
||||
//@todo: inner/outer cone, flags, cookie, flare
|
||||
} light_t;
|
||||
|
||||
API light_t light();
|
||||
// API void light_flags(int flags);
|
||||
API void light_type(light_t* l, char type);
|
||||
API void light_color(light_t* l, vec3 color);
|
||||
API void light_diffuse(light_t* l, vec3 color);
|
||||
API void light_specular(light_t* l, vec3 color);
|
||||
API void light_ambient(light_t* l, vec3 color);
|
||||
API void light_teleport(light_t* l, vec3 pos);
|
||||
API void light_dir(light_t* l, vec3 dir);
|
||||
API void light_radius(light_t* l, float radius);
|
||||
// API void light_cone(light_t* l, float inner, float outer);
|
||||
API void light_falloff(light_t* l, float constant, float linear, float quadratic);
|
||||
API void light_cone(light_t* l, float innerCone, float outerCone);
|
||||
API void light_update(unsigned num_lights, light_t *lv);
|
||||
|
||||
// scene
|
||||
|
@ -94,8 +101,6 @@ enum SCENE_FLAGS {
|
|||
};
|
||||
|
||||
typedef struct scene_t {
|
||||
handle program;
|
||||
|
||||
array(object_t) objs;
|
||||
array(light_t) lights;
|
||||
|
||||
|
|
75
engine/v4k.c
75
engine/v4k.c
|
@ -13947,6 +13947,24 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
|
|||
mat44 vp; multiply44x2(vp, proj, view);
|
||||
glUniformMatrix4fv( loc, 1, GL_FALSE, vp);
|
||||
}
|
||||
if( (loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0 ) {
|
||||
vec3 pos = vec3(view[3], view[6], view[9]);
|
||||
glUniform3fv( loc, 1, &pos.x );
|
||||
}
|
||||
else
|
||||
if( (loc = glGetUniformLocation(shader, "cam_pos")) >= 0 ) {
|
||||
vec3 pos = vec3(view[3], view[6], view[9]);
|
||||
glUniform3fv( loc, 1, &pos.x );
|
||||
}
|
||||
if( (loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0 ) {
|
||||
vec3 dir = vec3(view[0], view[1], view[2]);
|
||||
glUniform3fv( loc, 1, &dir.x );
|
||||
}
|
||||
else
|
||||
if( (loc = glGetUniformLocation(shader, "cam_dir")) >= 0 ) {
|
||||
vec3 dir = vec3(view[0], view[1], view[2]);
|
||||
glUniform3fv( loc, 1, &dir.x );
|
||||
}
|
||||
#if 0
|
||||
// @todo: mat44 projview (useful?)
|
||||
#endif
|
||||
|
@ -14383,13 +14401,14 @@ model_t model_from_mem(const void *mem, int len, int flags) {
|
|||
model_t m = {0};
|
||||
|
||||
const char *ptr = (const char *)mem;
|
||||
static int shaderprog = -1;
|
||||
if( shaderprog < 0 ) {
|
||||
// can't cache shader programs since we enable features via flags here
|
||||
// static int shaderprog = -1;
|
||||
// if( shaderprog < 0 ) {
|
||||
const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") }; // #define RIM
|
||||
shaderprog = shader(strlerp(1,symbols,vfs_read("shaders/vs_323444143_16_332_model.glsl")), strlerp(1,symbols,vfs_read("shaders/fs_32_4_model.glsl")), //fs,
|
||||
int shaderprog = shader(strlerp(1,symbols,vfs_read("shaders/vs_323444143_16_332_model.glsl")), strlerp(1,symbols,vfs_read("shaders/fs_32_4_model.glsl")), //fs,
|
||||
"att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor",
|
||||
(flags&MODEL_RIMLIGHT)?"RIM":NULL);
|
||||
}
|
||||
va("SHADING_PHONG,%s", (flags&MODEL_RIMLIGHT)?"RIM":""));
|
||||
// }
|
||||
|
||||
iqm_t *q = CALLOC(1, sizeof(iqm_t));
|
||||
program = shaderprog;
|
||||
|
@ -15852,9 +15871,13 @@ void object_billboard(object_t *obj, unsigned mode) {
|
|||
|
||||
light_t light() {
|
||||
light_t l = {0};
|
||||
l.color = vec3(1,1,1);
|
||||
l.radius = 2.5f;
|
||||
l.diffuse = vec3(1,1,1);
|
||||
l.dir = vec3(1,-1,-1);
|
||||
l.falloff.constant = 1.0f;
|
||||
l.falloff.linear = 0.09f;
|
||||
l.falloff.quadratic = 0.0032f;
|
||||
l.innerCone = 0.9f; // 25 deg
|
||||
l.outerCone = 0.85f; // 31 deg
|
||||
|
||||
return l;
|
||||
}
|
||||
|
@ -15864,9 +15887,19 @@ void light_type(light_t* l, char type) {
|
|||
l->type = type;
|
||||
}
|
||||
|
||||
void light_color(light_t* l, vec3 color) {
|
||||
void light_diffuse(light_t* l, vec3 color) {
|
||||
l->cached = 0;
|
||||
l->color = color;
|
||||
l->diffuse = color;
|
||||
}
|
||||
|
||||
void light_specular(light_t* l, vec3 color) {
|
||||
l->cached = 0;
|
||||
l->specular = color;
|
||||
}
|
||||
|
||||
void light_ambient(light_t* l, vec3 color) {
|
||||
l->cached = 0;
|
||||
l->ambient = color;
|
||||
}
|
||||
|
||||
void light_teleport(light_t* l, vec3 pos) {
|
||||
|
@ -15879,9 +15912,16 @@ void light_dir(light_t* l, vec3 dir) {
|
|||
l->dir = dir;
|
||||
}
|
||||
|
||||
void light_radius(light_t* l, float radius) {
|
||||
void light_falloff(light_t* l, float constant, float linear, float quadratic) {
|
||||
l->cached = 0;
|
||||
l->radius = radius;
|
||||
l->falloff.constant = constant;
|
||||
l->falloff.linear = linear;
|
||||
l->falloff.quadratic = quadratic;
|
||||
}
|
||||
|
||||
void light_cone(light_t* l, float innerCone, float outerCone) {
|
||||
l->innerCone = acos(innerCone);
|
||||
l->outerCone = acos(outerCone);
|
||||
}
|
||||
|
||||
void light_update(unsigned num_lights, light_t *lv) {
|
||||
|
@ -15890,9 +15930,16 @@ void light_update(unsigned num_lights, light_t *lv) {
|
|||
for (unsigned i=0; i < num_lights; ++i) {
|
||||
lv[i].cached = 1;
|
||||
shader_int(va("u_lights[%d].type", i), lv[i].type);
|
||||
shader_vec3(va("u_lights[%d].color", i), lv[i].color);
|
||||
shader_vec3(va("u_lights[%d].pos", i), lv[i].pos);
|
||||
shader_vec3(va("u_lights[%d].dir", i), lv[i].dir);
|
||||
shader_vec3(va("u_lights[%d].diffuse", i), lv[i].diffuse);
|
||||
shader_vec3(va("u_lights[%d].specular", i), lv[i].specular);
|
||||
shader_vec3(va("u_lights[%d].ambient", i), lv[i].ambient);
|
||||
shader_float(va("u_lights[%d].constant", i), lv[i].falloff.constant);
|
||||
shader_float(va("u_lights[%d].linear", i), lv[i].falloff.linear);
|
||||
shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic);
|
||||
shader_float(va("u_lights[%d].innerCone", i), lv[i].innerCone);
|
||||
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15913,8 +15960,6 @@ scene_t* scene_get_active() {
|
|||
|
||||
scene_t* scene_push() {
|
||||
scene_t *s = REALLOC(0, sizeof(scene_t)), clear = {0}; *s = clear;
|
||||
const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") };
|
||||
s->program = shader(strlerp(1, symbols, vfs_read("shaders/vs_332_32.glsl")), strlerp(1, symbols, vfs_read("shaders/fs_32_4_model.glsl")), "att_position,att_normal,att_texcoord,att_color", "fragcolor", NULL);
|
||||
s->skybox = skybox(NULL, 0);
|
||||
array_push(scenes, s);
|
||||
last_scene = s;
|
||||
|
@ -16025,7 +16070,6 @@ void scene_render(int flags) {
|
|||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glUseProgram(last_scene->program);
|
||||
|
||||
if(flags & SCENE_BACKGROUND) {
|
||||
if(last_scene->skybox.program) {
|
||||
|
@ -16046,7 +16090,6 @@ void scene_render(int flags) {
|
|||
|
||||
glDepthFunc(GL_LESS);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
// glUseProgram(last_scene->program);
|
||||
|
||||
// @fixme: CW ok for one-sided rendering. CCW ok for FXs. we need both
|
||||
(flags & SCENE_CULLFACE ? glEnable : glDisable)(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace(GL_CCW);
|
||||
|
|
29
engine/v4k.h
29
engine/v4k.h
|
@ -3005,6 +3005,14 @@ enum MODEL_FLAGS {
|
|||
MODEL_RIMLIGHT = 16
|
||||
};
|
||||
|
||||
//@todo: make this data-driven
|
||||
// enum SHADING_MODE {
|
||||
// SHADING_NONE,
|
||||
// SHADING_PHONG,
|
||||
// SHADING_CARTOON,
|
||||
// // SHADING_PBR,
|
||||
// };
|
||||
|
||||
typedef struct model_t {
|
||||
struct iqm_t *iqm; // private
|
||||
|
||||
|
@ -3247,21 +3255,28 @@ enum LIGHT_FLAGS {
|
|||
|
||||
typedef struct light_t {
|
||||
char type;
|
||||
vec3 color;
|
||||
vec3 diffuse, specular, ambient;
|
||||
vec3 pos, dir;
|
||||
float radius;
|
||||
struct {
|
||||
float constant, linear, quadratic;
|
||||
} falloff;
|
||||
float innerCone, outerCone;
|
||||
//@todo: cookie, flare
|
||||
|
||||
// internals
|
||||
bool cached; //< used by scene to invalidate cached light data
|
||||
//@todo: inner/outer cone, flags, cookie, flare
|
||||
} light_t;
|
||||
|
||||
API light_t light();
|
||||
// API void light_flags(int flags);
|
||||
API void light_type(light_t* l, char type);
|
||||
API void light_color(light_t* l, vec3 color);
|
||||
API void light_diffuse(light_t* l, vec3 color);
|
||||
API void light_specular(light_t* l, vec3 color);
|
||||
API void light_ambient(light_t* l, vec3 color);
|
||||
API void light_teleport(light_t* l, vec3 pos);
|
||||
API void light_dir(light_t* l, vec3 dir);
|
||||
API void light_radius(light_t* l, float radius);
|
||||
// API void light_cone(light_t* l, float inner, float outer);
|
||||
API void light_falloff(light_t* l, float constant, float linear, float quadratic);
|
||||
API void light_cone(light_t* l, float innerCone, float outerCone);
|
||||
API void light_update(unsigned num_lights, light_t *lv);
|
||||
|
||||
// scene
|
||||
|
@ -3275,8 +3290,6 @@ enum SCENE_FLAGS {
|
|||
};
|
||||
|
||||
typedef struct scene_t {
|
||||
handle program;
|
||||
|
||||
array(object_t) objs;
|
||||
array(light_t) lights;
|
||||
|
||||
|
|
Loading…
Reference in New Issue