示例#1
0
/*
* 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]);
}
示例#2
0
/*
* 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]);
}
示例#3
0
boost::optional<Eigen::Vector3f> read_depth_and_unproject(const Vector2i &screen_pos,
                                                          const Eigen::Matrix4f &model,
                                                          const Eigen::Matrix4f &proj,
                                                          const Vector2i &viewportSize, bool flipY) {
    float z = read_depth(screen_pos, flipY, viewportSize.y());
    if (z == 1.0f)
        return boost::none;
    return unproject(Eigen::Vector3f{(float)screen_pos.x(), (float)screen_pos.y(), z}, model, proj, viewportSize, flipY);
}
示例#4
0
static void
find_actual_mrd(GLdouble *next_to_near, GLdouble *next_to_far,
		GLdouble *actual_mrd_near, GLdouble *actual_mrd_far) 
{
	/* Here we use polygon offset to determine the implementation's actual
	 * MRD.
	 */

	double base_depth;

	glDepthFunc(GL_ALWAYS);

	/* Draw a quad far away from the eye and read the depth at its
	 * center:
	 */
	glDisable(GL_POLYGON_OFFSET_FILL);
	draw_quad_at_distance(*next_to_far);
	base_depth = read_depth(piglit_width/2, piglit_height/2);

	/* Now draw a quad that's one MRD closer to the eye: */
	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(0.0, -1.0);
	draw_quad_at_distance(*next_to_far);

	/* The difference between the depths of the two quads is the value the
	 * implementation is actually using for one MRD:
	 */
	*actual_mrd_far = base_depth
		- read_depth(piglit_width/2, piglit_height/2);

	/* Repeat the process for a quad close to the eye: */
	glDisable(GL_POLYGON_OFFSET_FILL);
	draw_quad_at_distance(*next_to_near);
	base_depth = read_depth(piglit_width / 2, piglit_height / 2);
	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(0.0, 1.0);	/* 1 MRD further away */
	draw_quad_at_distance(*next_to_near);
	*actual_mrd_near = read_depth(piglit_width / 2, piglit_height / 2)
		- base_depth;
}
示例#5
0
/*
* 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]);

}
示例#6
0
/*
* 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]);
}
示例#7
0
/*
* 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]);
}
示例#8
0
static bool
check_slope_offset(const struct angle_axis *aa, GLdouble *ideal_mrd_near)
{
	/* This function checks for correct slope-based offsets for a quad
	 * rotated to a given angle around a given axis.
	 *
	 * The basic strategy is to:
	 *	Draw the quad.  (Note: the quad's size and position
	 *		are chosen so that it won't ever be clipped.)
	 *	Sample three points in the quad's interior.
	 *	Compute dz/dx and dz/dy based on those samples.
	 *	Compute the range of allowable offsets; must be between
	 *		max(abs(dz/dx), abs(dz/dy)) and
	 *		sqrt((dz/dx)**2, (dz/dy)**2)
	 *	Sample the depth of the quad at its center.
	 *	Use PolygonOffset to produce an offset equal to one
	 *		times the depth slope of the base quad.
	 *	Draw another quad with the same orientation as the first.
	 *	Sample the second quad at its center.
	 *	Compute the difference in depths between the first quad
	 *		and the second.
	 *	Verify that the difference is within the allowable range.
	 *	Repeat for a third quad at twice the offset from the first.
	 *		(This verifies that the implementation is scaling
	 *		the depth offset correctly.)
	 */
	const GLfloat quad_dist = 2.5;	/* must be > 1+sqrt(2) to avoid */
					/* clipping by the near plane */
	GLdouble modelview_mat[16];
	GLdouble projection_mat[16];
	GLint viewport[4];
	GLdouble centerw[3];
	GLdouble base_depth;
	GLdouble p0[3];
	GLdouble p1[3];
	GLdouble p2[3];
	double det, dzdx, dzdy, mmax, mmin;
	GLdouble offset_depth, offset;


	glClearDepth(1.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);

	glColor3f(1.0, 0.0, 0.0); /* red */

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(0.0, 0.0, -quad_dist);
	glRotatef(aa->angle, aa->axis[0], aa->axis[1], aa->axis[2]);

	glGetDoublev(GL_MODELVIEW_MATRIX, modelview_mat);
	glGetDoublev(GL_PROJECTION_MATRIX, projection_mat);
	glGetIntegerv(GL_VIEWPORT, viewport);

	glDisable(GL_POLYGON_OFFSET_FILL);

	piglit_draw_rect(-1.0, -1.0, 2.0, 2.0);

	project(0.0, 0.0, 0.0, modelview_mat, projection_mat, viewport,
		centerw);
	base_depth = read_depth(centerw[0], centerw[1]);

	project(-0.9, -0.9, 0.0, modelview_mat, projection_mat, viewport, p0);
	p0[2] = read_depth(p0[0], p0[1]);

	project( 0.9, -0.9, 0.0, modelview_mat, projection_mat, viewport, p1);
	p1[2] = read_depth(p1[0], p1[1]);

	project( 0.9,  0.9, 0.0, modelview_mat, projection_mat, viewport, p2);
	p2[2] = read_depth(p2[0], p2[1]);

	det = (p0[0] - p1[0]) * (p0[1] - p2[1])
		- (p0[0] - p2[0]) * (p0[1] - p1[1]);
	if (fabs(det) < 0.001)
		return false;	/* too close to colinear to evaluate */

	dzdx = ((p0[2] - p1[2]) * (p0[1] - p2[1])
		- (p0[2] - p2[2]) * (p0[1] - p1[1])) / det;
	dzdy = ((p0[0] - p1[0]) * (p0[2] - p2[2])
		- (p0[0] - p2[0]) * (p0[2] - p1[2])) / det;

	mmax = 1.1 * sqrt(dzdx * dzdx + dzdy * dzdy) + (*ideal_mrd_near);
		/* (adding ideal_mrd_near is a fudge for roundoff error */
		/* when the slope is extremely close to zero) */
	mmin = 0.9 * fmax(fabs(dzdx), fabs(dzdy));

	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(-1.0, 0.0);
	piglit_present_results();
	piglit_draw_rect(-1.0, -1.0, 2.0, 2.0);
	offset_depth = read_depth(centerw[0], centerw[1]);
	offset = fmax(base_depth - offset_depth, 0.0);
	if (offset < mmin || offset > mmax) {
		if (offset < mmin)
			printf("Depth-slope related offset was too small");
		else
			printf("Depth-slope related offset was too large");
		printf("; first failure at:\n");
		printf("\tAngle = %f degrees, axis = (%f, %f, %f)\n",
			aa->angle, aa->axis[0], aa->axis[1], aa->axis[2]);
		printf("\tFailing offset was %.16f\n", offset);
		printf("\tAllowable range is (%f, %f)\n", mmin, mmax);
		return false;
	}

	glPolygonOffset(-2.0, 0.0);
	piglit_present_results();
	piglit_draw_rect(-1.0, -1.0, 2.0, 2.0);
	offset_depth = read_depth(centerw[0], centerw[1]);
	offset = fmax(base_depth - offset_depth, 0.0);
	if (offset < 2.0 * mmin || offset > 2.0 * mmax) {
		if (offset < 2.0 * mmin)
			printf("Depth-slope related offset was too small");
		else
			printf("Depth-slope related offset was too large");
		printf("; first failure at:\n");
		printf("\tAngle = %f degrees, axis = (%f, %f, %f)\n",
			aa->angle, aa->axis[0], aa->axis[1], aa->axis[2]);
		printf("\tFailing offset was %.16f\n", offset);
		printf("\tAllowable range is (%f, %f)\n", 2.0 * mmin, 
			2.0 * mmax);
		return false;
	}

	return true;
}