}
+static void clip_reset_stipple_counter( struct draw_stage *stage )
+{
+ stage->next->reset_stipple_counter( stage->next );
+}
+
+
/**
* Allocate a new clipper stage.
* \return pointer to new stage object
clipper->stage.line = clip_line;
clipper->stage.tri = clip_tri;
clipper->stage.end = clip_end;
+ clipper->stage.reset_stipple_counter = clip_reset_stipple_counter;
clipper->plane = draw->plane;
}
+static void cull_reset_stipple_counter( struct draw_stage *stage )
+{
+ stage->next->reset_stipple_counter( stage->next );
+}
+
/**
* Create a new polygon culling stage.
*/
cull->stage.line = cull_line;
cull->stage.tri = cull_tri;
cull->stage.end = cull_end;
+ cull->stage.reset_stipple_counter = cull_reset_stipple_counter;
return &cull->stage;
}
}
+static void flatshade_reset_stipple_counter( struct draw_stage *stage )
+{
+ stage->next->reset_stipple_counter( stage->next );
+}
+
+
/**
* Create flatshading drawing stage.
*/
flatshade->stage.line = flatshade_line;
flatshade->stage.tri = flatshade_tri;
flatshade->stage.end = flatshade_end;
+ flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter;
flatshade->lookup = draw->vf_attr_to_slot;
}
+static void offset_reset_stipple_counter( struct draw_stage *stage )
+{
+ stage->next->reset_stipple_counter( stage->next );
+}
+
+
/**
* Create polygon offset drawing stage.
*/
offset->stage.line = offset_line;
offset->stage.tri = offset_tri;
offset->stage.end = offset_end;
+ offset->stage.reset_stipple_counter = offset_reset_stipple_counter;
return &offset->stage;
}
struct prim_header * );
void (*end)( struct draw_stage * );
+
+ void (*reset_stipple_counter)( struct draw_stage * );
};
}
+static void twoside_reset_stipple_counter( struct draw_stage *stage )
+{
+ stage->next->reset_stipple_counter( stage->next );
+}
+
+
/**
* Create twoside pipeline stage.
*/
twoside->stage.line = twoside_line;
twoside->stage.tri = twoside_tri;
twoside->stage.end = twoside_end;
+ twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter;
twoside->lookup = draw->vf_attr_to_slot;
}
+static void unfilled_reset_stipple_counter( struct draw_stage *stage )
+{
+ stage->next->reset_stipple_counter( stage->next );
+}
+
+
/**
* Create unfilled triangle stage.
*/
unfilled->stage.line = unfilled_line;
unfilled->stage.tri = unfilled_tri;
unfilled->stage.end = unfilled_end;
+ unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter;
return &unfilled->stage;
}
prim.v[0] = get_vertex( draw, elts[i + 0] );
prim.v[1] = get_vertex( draw, elts[i + 1] );
+ first->reset_stipple_counter( first );
first->line( first, &prim );
}
break;
case GL_LINE_LOOP:
if (count >= 2) {
+ first->reset_stipple_counter( first );
for (i = 1; i < count; i++) {
prim.v[0] = get_vertex( draw, elts[i-1] );
prim.v[1] = get_vertex( draw, elts[i] );
* require more complex code here.
*/
if (count >= 2) {
+ first->reset_stipple_counter( first );
prim.v[0] = 0;
prim.v[1] = get_vertex( draw, elts[0] );
for (i = 0; i+1 < count; i += 2) {
prim.v[0] = get_vertex( draw, start + i + 0 );
prim.v[1] = get_vertex( draw, start + i + 1 );
-
+
+ first->reset_stipple_counter( first );
first->line( first, &prim );
}
break;
case GL_LINE_LOOP:
if (count >= 2) {
+ first->reset_stipple_counter( first );
for (i = 1; i < count; i++) {
prim.v[0] = get_vertex( draw, start + i - 1 );
prim.v[1] = get_vertex( draw, start + i );
case GL_LINE_STRIP:
if (count >= 2) {
+ first->reset_stipple_counter( first );
prim.v[0] = 0;
prim.v[1] = get_vertex( draw, start + 0 );
GLboolean need_z; /**< produce quad/fragment Z values? */
GLboolean need_w; /**< produce quad/fragment W values? */
+#if 0
/* Stipple derived state:
*/
GLubyte stipple_masks[16][16];
+#endif
GLuint occlusion_counter;
+ GLuint line_stipple_counter;
+
/** Software quad rendering pipeline */
struct {
struct quad_stage *polygon_stipple;
}
+/**
+ * Determine whether or not to emit a line fragment by checking
+ * line stipple pattern.
+ */
+static INLINE GLuint
+stipple_test(GLint counter, GLushort pattern, GLint factor)
+{
+ GLint b = (counter / factor) & 0xf;
+ return (1 << b) & pattern;
+}
+
/**
* Do setup for line rasterization, then render the line.
const struct vertex_header *v0 = prim->v[0];
const struct vertex_header *v1 = prim->v[1];
struct setup_stage *setup = setup_stage( stage );
+ struct softpipe_context *sp = setup->softpipe;
GLint x0 = (GLint) v0->data[0][0];
GLint x1 = (GLint) v1->data[0][0];
const GLint errorDec = error - dx;
for (i = 0; i < dx; i++) {
- plot(setup, x0, y0);
+ if (!sp->setup.line_stipple_enable ||
+ stipple_test(sp->line_stipple_counter,
+ sp->setup.line_stipple_pattern,
+ sp->setup.line_stipple_factor + 1)) {
+ plot(setup, x0, y0);
+ }
x0 += xstep;
if (error < 0) {
error += errorDec;
y0 += ystep;
}
+
+ sp->line_stipple_counter++;
}
}
else {
const GLint errorDec = error - dy;
for (i = 0; i < dy; i++) {
- plot(setup, x0, y0);
+ if (!sp->setup.line_stipple_enable ||
+ stipple_test(sp->line_stipple_counter,
+ sp->setup.line_stipple_pattern,
+ sp->setup.line_stipple_factor + 1)) {
+ plot(setup, x0, y0);
+ }
y0 += ystep;
error += errorDec;
x0 += xstep;
}
+
+ sp->line_stipple_counter++;
}
}
}
+static void reset_stipple_counter( struct draw_stage *stage )
+{
+ struct setup_stage *setup = setup_stage(stage);
+ setup->softpipe->line_stipple_counter = 0;
+}
+
+
/**
* Create a new primitive setup/render stage.
*/
setup->stage.line = setup_line;
setup->stage.tri = setup_tri;
setup->stage.end = setup_end;
+ setup->stage.reset_stipple_counter = reset_stipple_counter;
setup->quad.coef = setup->coef;