draw_pipe_wide_line.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  * 
00026  **************************************************************************/
00027 
00028 /* Authors:  Keith Whitwell <keith@tungstengraphics.com>
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    /*const struct wideline_stage *wide = wideline_stage(stage);*/
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    /* small tweak to meet GL specification */
00081    const float bias = 0.125f;
00082 
00083    /*
00084     * Draw wide line as a quad (two tris) by "stretching" the line along
00085     * X or Y.
00086     * We need to tweak coords in several ways to be conformant here.
00087     */
00088 
00089    if (dx > dy) {
00090       /* x-major line */
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          /* left to right line */
00097          pos0[0] -= 0.5f;
00098          pos1[0] -= 0.5f;
00099          pos2[0] -= 0.5f;
00100          pos3[0] -= 0.5f;
00101       }
00102       else {
00103          /* right to left line */
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       /* y-major line */
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          /* top to bottom line */
00118          pos0[1] -= 0.5f;
00119          pos1[1] -= 0.5f;
00120          pos2[1] -= 0.5f;
00121          pos3[1] -= 0.5f;
00122       }
00123       else {
00124          /* bottom to top line */
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;  /* only the sign matters */
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 }

Generated on Tue Sep 29 06:25:14 2009 for Gallium3D by  doxygen 1.5.4