00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "pipe/p_defines.h"
00032 #include "pipe/p_shader_tokens.h"
00033 #include "util/u_math.h"
00034 #include "util/u_memory.h"
00035 #include "draw_private.h"
00036 #include "draw_pipe.h"
00037
00038
00039 struct wideline_stage {
00040 struct draw_stage stage;
00041
00042 float half_line_width;
00043 };
00044
00045
00046
00047 static INLINE struct wideline_stage *wideline_stage( struct draw_stage *stage )
00048 {
00049 return (struct wideline_stage *)stage;
00050 }
00051
00052
00053
00058 static void wideline_line( struct draw_stage *stage,
00059 struct prim_header *header )
00060 {
00061
00062 const unsigned pos = stage->draw->vs.position_output;
00063 const float half_width = 0.5f * stage->draw->rasterizer->line_width;
00064
00065 struct prim_header tri;
00066
00067 struct vertex_header *v0 = dup_vert(stage, header->v[0], 0);
00068 struct vertex_header *v1 = dup_vert(stage, header->v[0], 1);
00069 struct vertex_header *v2 = dup_vert(stage, header->v[1], 2);
00070 struct vertex_header *v3 = dup_vert(stage, header->v[1], 3);
00071
00072 float *pos0 = v0->data[pos];
00073 float *pos1 = v1->data[pos];
00074 float *pos2 = v2->data[pos];
00075 float *pos3 = v3->data[pos];
00076
00077 const float dx = fabsf(pos0[0] - pos2[0]);
00078 const float dy = fabsf(pos0[1] - pos2[1]);
00079
00080
00081 const float bias = 0.125f;
00082
00083
00084
00085
00086
00087
00088
00089 if (dx > dy) {
00090
00091 pos0[1] = pos0[1] - half_width - bias;
00092 pos1[1] = pos1[1] + half_width - bias;
00093 pos2[1] = pos2[1] - half_width - bias;
00094 pos3[1] = pos3[1] + half_width - bias;
00095 if (pos0[0] < pos2[0]) {
00096
00097 pos0[0] -= 0.5f;
00098 pos1[0] -= 0.5f;
00099 pos2[0] -= 0.5f;
00100 pos3[0] -= 0.5f;
00101 }
00102 else {
00103
00104 pos0[0] += 0.5f;
00105 pos1[0] += 0.5f;
00106 pos2[0] += 0.5f;
00107 pos3[0] += 0.5f;
00108 }
00109 }
00110 else {
00111
00112 pos0[0] = pos0[0] - half_width + bias;
00113 pos1[0] = pos1[0] + half_width + bias;
00114 pos2[0] = pos2[0] - half_width + bias;
00115 pos3[0] = pos3[0] + half_width + bias;
00116 if (pos0[1] < pos2[1]) {
00117
00118 pos0[1] -= 0.5f;
00119 pos1[1] -= 0.5f;
00120 pos2[1] -= 0.5f;
00121 pos3[1] -= 0.5f;
00122 }
00123 else {
00124
00125 pos0[1] += 0.5f;
00126 pos1[1] += 0.5f;
00127 pos2[1] += 0.5f;
00128 pos3[1] += 0.5f;
00129 }
00130 }
00131
00132 tri.det = header->det;
00133 tri.v[0] = v0;
00134 tri.v[1] = v2;
00135 tri.v[2] = v3;
00136 stage->next->tri( stage->next, &tri );
00137
00138 tri.v[0] = v0;
00139 tri.v[1] = v3;
00140 tri.v[2] = v1;
00141 stage->next->tri( stage->next, &tri );
00142 }
00143
00144
00145 static void wideline_flush( struct draw_stage *stage, unsigned flags )
00146 {
00147 stage->next->flush( stage->next, flags );
00148 }
00149
00150
00151 static void wideline_reset_stipple_counter( struct draw_stage *stage )
00152 {
00153 stage->next->reset_stipple_counter( stage->next );
00154 }
00155
00156
00157 static void wideline_destroy( struct draw_stage *stage )
00158 {
00159 draw_free_temp_verts( stage );
00160 FREE( stage );
00161 }
00162
00163
00164 struct draw_stage *draw_wide_line_stage( struct draw_context *draw )
00165 {
00166 struct wideline_stage *wide = CALLOC_STRUCT(wideline_stage);
00167
00168 draw_alloc_temp_verts( &wide->stage, 4 );
00169
00170 wide->stage.draw = draw;
00171 wide->stage.next = NULL;
00172 wide->stage.point = draw_pipe_passthrough_point;
00173 wide->stage.line = wideline_line;
00174 wide->stage.tri = draw_pipe_passthrough_tri;
00175 wide->stage.flush = wideline_flush;
00176 wide->stage.reset_stipple_counter = wideline_reset_stipple_counter;
00177 wide->stage.destroy = wideline_destroy;
00178
00179 return &wide->stage;
00180 }