/* * Fragment shader for axis and arrows. */ static void fragment_shader_axis(int y, int x, struct fragment_input *input, struct uniform_variables *vars){ if(input->frag_coord[VAR_Z] >= read_depth(y, x)){ return; } write_color(y, x, input->attributes[0], input->attributes[1], input->attributes[2], 1.0f); write_depth(y, x, input->frag_coord[VAR_Z]); }
/* * Fragment shader for surface color based on surface normals. */ static void fragment_shader_color(int y, int x, struct fragment_input *input, struct uniform_variables *vars){ if(input->frag_coord[VAR_Z] >= read_depth(y, x)){ return; } vec3 object_normal; object_normal[VAR_X] = input->attributes[0] / input->frag_coord[VAR_W]; object_normal[VAR_Y] = input->attributes[1] / input->frag_coord[VAR_W]; object_normal[VAR_Z] = input->attributes[2] / input->frag_coord[VAR_W]; normalize_vec3(object_normal); if(input->front_facing == ER_FALSE){ object_normal[VAR_X] = -object_normal[VAR_X]; object_normal[VAR_Y] = -object_normal[VAR_Y]; object_normal[VAR_Z] = -object_normal[VAR_Z]; } float red, green, blue; red = (object_normal[VAR_X] * 0.5f + 0.5f); red = clamp(red, 0.0f, 1.0f); green = (object_normal[VAR_Y] * 0.5f + 0.5f); green = clamp(green, 0.0f, 1.0f); blue = (object_normal[VAR_X] * 0.5f + 0.5f); blue = clamp(blue, 0.0f, 1.0f); write_color(y, x, red, green, blue, 1.0f); write_depth(y, x, input->frag_coord[VAR_Z]); }
/* * Fragment shader for surface lighting. One directional light source, phong shading. */ static void fragment_shader_light(int y, int x, struct fragment_input *input, struct uniform_variables *vars){ if(input->frag_coord[VAR_Z] >= read_depth(y, x)){ return; } float *light_dir = &(vars->uniform_float[0]); vec3 eye_normal, object_normal; object_normal[VAR_X] = input->attributes[0] / input->frag_coord[VAR_W]; object_normal[VAR_Y] = input->attributes[1] / input->frag_coord[VAR_W]; object_normal[VAR_Z] = input->attributes[2] / input->frag_coord[VAR_W]; eye_normal[VAR_X] = input->attributes[3] / input->frag_coord[VAR_W]; eye_normal[VAR_Y] = input->attributes[4] / input->frag_coord[VAR_W]; eye_normal[VAR_Z] = input->attributes[5] / input->frag_coord[VAR_W]; normalize_vec3(eye_normal); normalize_vec3(object_normal); if(input->front_facing == ER_FALSE){ eye_normal[VAR_X] = -eye_normal[VAR_X]; eye_normal[VAR_Y] = -eye_normal[VAR_Y]; eye_normal[VAR_Z] = -eye_normal[VAR_Z]; object_normal[VAR_X] = -object_normal[VAR_X]; object_normal[VAR_Y] = -object_normal[VAR_Y]; object_normal[VAR_Z] = -object_normal[VAR_Z]; } float diffuse_term = max(0.0f, dot_vec3(light_dir, eye_normal) ); float specular_term = 0.0f; vec3 view_vector; vec3 half_vector; view_vector[VAR_X] = 0.0f; view_vector[VAR_Y] = 0.0f; view_vector[VAR_Z] = 1.0f; if(diffuse_term > 0.0f){ half_vector[VAR_X] = light_dir[VAR_X] + view_vector[VAR_X]; half_vector[VAR_Y] = light_dir[VAR_Y] + view_vector[VAR_Y]; half_vector[VAR_Z] = light_dir[VAR_Z] + view_vector[VAR_Z]; normalize_vec3(half_vector); specular_term = pow( max(0.0f, dot_vec3(half_vector, eye_normal)), 50.0f ); } float red, green, blue, light_intensity; light_intensity = 0.6f * diffuse_term + 0.4f * specular_term; red = (object_normal[VAR_X] * 0.5f + 0.5f) * light_intensity; red = clamp(red, 0.0f, 1.0f); green = (object_normal[VAR_Y] * 0.5f + 0.5f) * light_intensity; green = clamp(green, 0.0f, 1.0f); blue = (object_normal[VAR_Z] * 0.5f + 0.5f) * light_intensity; blue = clamp(blue, 0.0f, 1.0f); write_color(y, x, red, green, blue, 1.0f); write_depth(y, x, input->frag_coord[VAR_Z]); }
/* * Fragment shader for texture mapped cube. */ static void fs_cube(int y, int x, struct fragment_input *input, struct uniform_variables *vars){ if(input->frag_coord[VAR_Z] >= read_depth(y, x)){ return; } struct texture* tex = vars->uniform_texture[0]; vec2 tex_coord; vec4 tex_color; tex_coord[VAR_S] = input->attributes[0] / input->frag_coord[VAR_W]; tex_coord[VAR_T] = input->attributes[1] / input->frag_coord[VAR_W]; texture_lod(tex, tex_coord, 0.0f, tex_color); write_color(y, x, tex_color[0], tex_color[1], tex_color[2], 1.0f); write_depth(y, x, input->frag_coord[VAR_Z]); }
struct tree_node * write_var(FILE *out, struct tree_node *t, struct lacy_env *env) { if (0 == strcmp(t->buffer.s, "root")) { write_depth(out, env); } else if (0 == strcmp(t->buffer.s, "this")) { struct page *p = env_get_page_top(env); if (NULL != p) { if (t->next != NULL && MEMBER == t->next->token) { t = t->next->next; t = write_member(out, t, p, env); } else { fprintf(out, "%s", p->file_path); } } } else { if (env_has_next(env)) { struct page_attr *a; a = env_attr_lookup(env, t->buffer.s); if (t->next != NULL && MEMBER == t->next->token) { t = t->next->next; if (NULL != a) { struct page *p = page_find(a->value.s); t = write_member(out, t, p, env); } } else { if (NULL != a) { fprintf(out, "%s", a->value.s); } } } } return t; }
/* * Fragment shader for texture mapped cube. Calculation of perspective correct derivatives for trilinear filtering. */ static void fs_cube_grad(int y, int x, struct fragment_input *input, struct uniform_variables *vars){ if(input->frag_coord[VAR_Z] >= read_depth(y, x)){ return; } struct texture *tex = vars->uniform_texture[0]; vec2 tex_coord; vec4 tex_color; tex_coord[VAR_S] = input->attributes[0] / input->frag_coord[VAR_W]; tex_coord[VAR_T] = input->attributes[1] / input->frag_coord[VAR_W]; vec2 ddx, ddy; float one_over_w2 = 1.0f / (input->frag_coord[VAR_W] * input->frag_coord[VAR_W]); ddx[VAR_S] = (input->ddx[0] * input->frag_coord[VAR_W] - input->attributes[0] * input->dw_dx) * one_over_w2; ddx[VAR_T] = (input->ddx[1] * input->frag_coord[VAR_W] - input->attributes[1] * input->dw_dx) * one_over_w2; ddy[VAR_S] = (input->ddy[0] * input->frag_coord[VAR_W] - input->attributes[0] * input->dw_dy) * one_over_w2; ddy[VAR_T] = (input->ddy[1] * input->frag_coord[VAR_W] - input->attributes[1] * input->dw_dy) * one_over_w2; texture_grad(tex, tex_coord, ddx, ddy, tex_color); write_color(y, x, tex_color[0], tex_color[1], tex_color[2], 1.0f); write_depth(y, x, input->frag_coord[VAR_Z]); }