Implement line stippling.
Also added draw_stage::reset_line_stipple(). There may be a better way of doing that though.
This commit is contained in:
@@ -433,6 +433,12 @@ static void clip_end( struct draw_stage *stage )
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
@@ -449,6 +455,7 @@ struct draw_stage *draw_clip_stage( struct draw_context *draw )
|
||||
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;
|
||||
|
||||
|
@@ -111,6 +111,11 @@ static void cull_end( struct draw_stage *stage )
|
||||
}
|
||||
|
||||
|
||||
static void cull_reset_stipple_counter( struct draw_stage *stage )
|
||||
{
|
||||
stage->next->reset_stipple_counter( stage->next );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new polygon culling stage.
|
||||
*/
|
||||
@@ -127,6 +132,7 @@ struct draw_stage *draw_cull_stage( struct draw_context *draw )
|
||||
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;
|
||||
}
|
||||
|
@@ -130,6 +130,12 @@ static void flatshade_end( struct draw_stage *stage )
|
||||
}
|
||||
|
||||
|
||||
static void flatshade_reset_stipple_counter( struct draw_stage *stage )
|
||||
{
|
||||
stage->next->reset_stipple_counter( stage->next );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create flatshading drawing stage.
|
||||
*/
|
||||
@@ -146,6 +152,7 @@ struct draw_stage *draw_flatshade_stage( struct draw_context *draw )
|
||||
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;
|
||||
|
||||
|
@@ -145,6 +145,12 @@ static void offset_end( struct draw_stage *stage )
|
||||
}
|
||||
|
||||
|
||||
static void offset_reset_stipple_counter( struct draw_stage *stage )
|
||||
{
|
||||
stage->next->reset_stipple_counter( stage->next );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create polygon offset drawing stage.
|
||||
*/
|
||||
@@ -161,6 +167,7 @@ struct draw_stage *draw_offset_stage( struct draw_context *draw )
|
||||
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;
|
||||
}
|
||||
|
@@ -98,6 +98,8 @@ struct draw_stage
|
||||
struct prim_header * );
|
||||
|
||||
void (*end)( struct draw_stage * );
|
||||
|
||||
void (*reset_stipple_counter)( struct draw_stage * );
|
||||
};
|
||||
|
||||
|
||||
|
@@ -139,6 +139,12 @@ static void twoside_end( struct draw_stage *stage )
|
||||
}
|
||||
|
||||
|
||||
static void twoside_reset_stipple_counter( struct draw_stage *stage )
|
||||
{
|
||||
stage->next->reset_stipple_counter( stage->next );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create twoside pipeline stage.
|
||||
*/
|
||||
@@ -155,6 +161,7 @@ struct draw_stage *draw_twoside_stage( struct draw_context *draw )
|
||||
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;
|
||||
|
||||
|
@@ -156,6 +156,12 @@ static void unfilled_end( struct draw_stage *stage )
|
||||
}
|
||||
|
||||
|
||||
static void unfilled_reset_stipple_counter( struct draw_stage *stage )
|
||||
{
|
||||
stage->next->reset_stipple_counter( stage->next );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create unfilled triangle stage.
|
||||
*/
|
||||
@@ -173,6 +179,7 @@ struct draw_stage *draw_unfilled_stage( struct draw_context *draw )
|
||||
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;
|
||||
}
|
||||
|
@@ -151,12 +151,14 @@ static void draw_indexed_prim( struct draw_context *draw,
|
||||
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] );
|
||||
@@ -178,6 +180,7 @@ static void draw_indexed_prim( struct draw_context *draw,
|
||||
* 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] );
|
||||
|
||||
@@ -314,12 +317,14 @@ static void draw_prim( struct draw_context *draw,
|
||||
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 );
|
||||
@@ -334,6 +339,7 @@ static void draw_prim( struct draw_context *draw,
|
||||
|
||||
case GL_LINE_STRIP:
|
||||
if (count >= 2) {
|
||||
first->reset_stipple_counter( first );
|
||||
prim.v[0] = 0;
|
||||
prim.v[1] = get_vertex( draw, start + 0 );
|
||||
|
||||
|
@@ -111,12 +111,16 @@ struct softpipe_context {
|
||||
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;
|
||||
|
@@ -706,6 +706,17 @@ plot(struct setup_stage *setup, GLint x, GLint y)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -718,6 +729,7 @@ setup_line(struct draw_stage *stage, struct prim_header *prim)
|
||||
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];
|
||||
@@ -763,7 +775,12 @@ setup_line(struct draw_stage *stage, struct prim_header *prim)
|
||||
const GLint errorDec = error - dx;
|
||||
|
||||
for (i = 0; i < dx; i++) {
|
||||
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) {
|
||||
@@ -773,6 +790,8 @@ setup_line(struct draw_stage *stage, struct prim_header *prim)
|
||||
error += errorDec;
|
||||
y0 += ystep;
|
||||
}
|
||||
|
||||
sp->line_stipple_counter++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -783,7 +802,12 @@ setup_line(struct draw_stage *stage, struct prim_header *prim)
|
||||
const GLint errorDec = error - dy;
|
||||
|
||||
for (i = 0; i < dy; i++) {
|
||||
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;
|
||||
|
||||
@@ -794,6 +818,8 @@ setup_line(struct draw_stage *stage, struct prim_header *prim)
|
||||
error += errorDec;
|
||||
x0 += xstep;
|
||||
}
|
||||
|
||||
sp->line_stipple_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -984,6 +1010,13 @@ static void setup_end( struct draw_stage *stage )
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
*/
|
||||
@@ -998,6 +1031,7 @@ struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe )
|
||||
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;
|
||||
|
||||
|
Reference in New Issue
Block a user