/* Interpolate between two vertices to produce a third. */ static void interp( const struct clipper *clip, struct vertex_header *dst, float t, const struct vertex_header *out, const struct vertex_header *in ) { const unsigned nr_attrs = clip->stage.draw->vs.num_vs_outputs; const unsigned pos_attr = clip->stage.draw->vs.position_output; unsigned j; /* Vertex header. */ { dst->clipmask = 0; dst->edgeflag = 0; /* will get overwritten later */ dst->pad = 0; dst->vertex_id = UNDEFINED_VERTEX_ID; } /* Clip coordinates: interpolate normally */ { interp_attr(dst->clip, t, in->clip, out->clip); } /* Do the projective divide and insert window coordinates: */ { const float *pos = dst->clip; const float *scale = clip->stage.draw->viewport.scale; const float *trans = clip->stage.draw->viewport.translate; const float oow = 1.0f / pos[3]; dst->data[pos_attr][0] = pos[0] * oow * scale[0] + trans[0]; dst->data[pos_attr][1] = pos[1] * oow * scale[1] + trans[1]; dst->data[pos_attr][2] = pos[2] * oow * scale[2] + trans[2]; dst->data[pos_attr][3] = oow; } /* Other attributes */ for (j = 0; j < nr_attrs; j++) { if (j != pos_attr) interp_attr(dst->data[j], t, in->data[j], out->data[j]); } }
/* Interpolate between two vertices to produce a third. */ static void interp( const struct clip_stage *clip, struct vertex_header *dst, float t, const struct vertex_header *out, const struct vertex_header *in ) { const unsigned nr_attrs = draw_current_shader_outputs(clip->stage.draw); const unsigned pos_attr = draw_current_shader_position_output(clip->stage.draw); unsigned j; /* Vertex header. */ dst->clipmask = 0; dst->edgeflag = 0; /* will get overwritten later */ dst->pad = 0; dst->vertex_id = UNDEFINED_VERTEX_ID; /* Interpolate the clip-space coords. */ interp_attr(dst->clip, t, in->clip, out->clip); /* Do the projective divide and viewport transformation to get * new window coordinates: */ { const float *pos = dst->clip; const float *scale = clip->stage.draw->viewport.scale; const float *trans = clip->stage.draw->viewport.translate; const float oow = 1.0f / pos[3]; dst->data[pos_attr][0] = pos[0] * oow * scale[0] + trans[0]; dst->data[pos_attr][1] = pos[1] * oow * scale[1] + trans[1]; dst->data[pos_attr][2] = pos[2] * oow * scale[2] + trans[2]; dst->data[pos_attr][3] = oow; } /* Other attributes */ for (j = 0; j < nr_attrs; j++) { if (j != pos_attr) interp_attr(dst->data[j], t, in->data[j], out->data[j]); } }
/* Interpolate between two vertices to produce a third. */ static void interp( const struct clip_stage *clip, struct vertex_header *dst, float t, const struct vertex_header *out, const struct vertex_header *in, unsigned viewport_index ) { const unsigned nr_attrs = draw_num_shader_outputs(clip->stage.draw); const unsigned pos_attr = draw_current_shader_position_output(clip->stage.draw); const unsigned clip_attr = draw_current_shader_clipvertex_output(clip->stage.draw); unsigned j; float t_nopersp; /* Vertex header. */ dst->clipmask = 0; dst->edgeflag = 0; /* will get overwritten later */ dst->have_clipdist = in->have_clipdist; dst->vertex_id = UNDEFINED_VERTEX_ID; /* Interpolate the clip-space coords. */ interp_attr(dst->clip, t, in->clip, out->clip); /* interpolate the clip-space position */ interp_attr(dst->pre_clip_pos, t, in->pre_clip_pos, out->pre_clip_pos); /* Do the projective divide and viewport transformation to get * new window coordinates: */ { const float *pos = dst->pre_clip_pos; const float *scale = clip->stage.draw->viewports[viewport_index].scale; const float *trans = clip->stage.draw->viewports[viewport_index].translate; const float oow = 1.0f / pos[3]; dst->data[pos_attr][0] = pos[0] * oow * scale[0] + trans[0]; dst->data[pos_attr][1] = pos[1] * oow * scale[1] + trans[1]; dst->data[pos_attr][2] = pos[2] * oow * scale[2] + trans[2]; dst->data[pos_attr][3] = oow; } /** * Compute the t in screen-space instead of 3d space to use * for noperspective interpolation. * * The points can be aligned with the X axis, so in that case try * the Y. When both points are at the same screen position, we can * pick whatever value (the interpolated point won't be in front * anyway), so just use the 3d t. */ { int k; t_nopersp = t; /* find either in.x != out.x or in.y != out.y */ for (k = 0; k < 2; k++) { if (in->clip[k] != out->clip[k]) { /* do divide by W, then compute linear interpolation factor */ float in_coord = in->clip[k] / in->clip[3]; float out_coord = out->clip[k] / out->clip[3]; float dst_coord = dst->clip[k] / dst->clip[3]; t_nopersp = (dst_coord - out_coord) / (in_coord - out_coord); break; } } } /* Other attributes */ for (j = 0; j < nr_attrs; j++) { if (j != pos_attr && j != clip_attr) { if (clip->noperspective_attribs[j]) interp_attr(dst->data[j], t_nopersp, in->data[j], out->data[j]); else interp_attr(dst->data[j], t, in->data[j], out->data[j]); } } }