draw_pipe_wide_line.c revision 89d8577fb3036547ef0b47498cc8dc5c77f886e0
1b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul/************************************************************************** 2b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * 3b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * All Rights Reserved. 5b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * 6b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * Permission is hereby granted, free of charge, to any person obtaining a 7b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * copy of this software and associated documentation files (the 8b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * "Software"), to deal in the Software without restriction, including 9b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * without limitation the rights to use, copy, modify, merge, publish, 10b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * distribute, sub license, and/or sell copies of the Software, and to 11b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * permit persons to whom the Software is furnished to do so, subject to 12b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * the following conditions: 13b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * 14b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * The above copyright notice and this permission notice (including the 15b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * next paragraph) shall be included in all copies or substantial portions 16b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * of the Software. 17b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * 18b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * 26b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul **************************************************************************/ 27b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 28b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul/* Authors: Keith Whitwell <keith@tungstengraphics.com> 29b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul */ 30b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 31b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul#include "pipe/p_defines.h" 32b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul#include "pipe/p_shader_tokens.h" 334f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_math.h" 344f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h" 35b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul#include "draw_private.h" 36507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwell#include "draw_pipe.h" 37b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 38b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 39b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paulstruct wideline_stage { 40b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul struct draw_stage stage; 41b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 42b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul float half_line_width; 43b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul}; 44b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 45b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 46b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 47b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paulstatic INLINE struct wideline_stage *wideline_stage( struct draw_stage *stage ) 48b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul{ 49b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul return (struct wideline_stage *)stage; 50b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul} 51b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 52b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 53b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 54b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul/** 55b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * Draw a wide line by drawing a quad (two triangles). 56b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * XXX need to disable polygon stipple. 57b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul */ 58b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paulstatic void wideline_line( struct draw_stage *stage, 59b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul struct prim_header *header ) 60b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul{ 61b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul /*const struct wideline_stage *wide = wideline_stage(stage);*/ 6289d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin const unsigned pos = draw_current_shader_position_output(stage->draw); 63b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul const float half_width = 0.5f * stage->draw->rasterizer->line_width; 64b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 65b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul struct prim_header tri; 66b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 67b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); 68b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); 69b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); 70b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); 71b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 722161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell float *pos0 = v0->data[pos]; 732161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell float *pos1 = v1->data[pos]; 742161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell float *pos2 = v2->data[pos]; 752161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell float *pos3 = v3->data[pos]; 76b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 77120270def74149b240926f827b80ca073536d462Brian Paul const float dx = fabsf(pos0[0] - pos2[0]); 78120270def74149b240926f827b80ca073536d462Brian Paul const float dy = fabsf(pos0[1] - pos2[1]); 792a121e8e2289d2ca136f511c5a6ef049f9c99ec4Brian Paul 802a121e8e2289d2ca136f511c5a6ef049f9c99ec4Brian Paul /* small tweak to meet GL specification */ 812a121e8e2289d2ca136f511c5a6ef049f9c99ec4Brian Paul const float bias = 0.125f; 822a121e8e2289d2ca136f511c5a6ef049f9c99ec4Brian Paul 83b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul /* 84b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * Draw wide line as a quad (two tris) by "stretching" the line along 85b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * X or Y. 86b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul * We need to tweak coords in several ways to be conformant here. 87b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul */ 88b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 89b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul if (dx > dy) { 90b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul /* x-major line */ 912a121e8e2289d2ca136f511c5a6ef049f9c99ec4Brian Paul pos0[1] = pos0[1] - half_width - bias; 922a121e8e2289d2ca136f511c5a6ef049f9c99ec4Brian Paul pos1[1] = pos1[1] + half_width - bias; 932a121e8e2289d2ca136f511c5a6ef049f9c99ec4Brian Paul pos2[1] = pos2[1] - half_width - bias; 942a121e8e2289d2ca136f511c5a6ef049f9c99ec4Brian Paul pos3[1] = pos3[1] + half_width - bias; 95b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul if (pos0[0] < pos2[0]) { 96b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul /* left to right line */ 97b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos0[0] -= 0.5f; 98b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos1[0] -= 0.5f; 99b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos2[0] -= 0.5f; 100b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos3[0] -= 0.5f; 101b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul } 102b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul else { 103b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul /* right to left line */ 104b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos0[0] += 0.5f; 105b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos1[0] += 0.5f; 106b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos2[0] += 0.5f; 107b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos3[0] += 0.5f; 108b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul } 109b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul } 110b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul else { 111b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul /* y-major line */ 1122a121e8e2289d2ca136f511c5a6ef049f9c99ec4Brian Paul pos0[0] = pos0[0] - half_width + bias; 1132a121e8e2289d2ca136f511c5a6ef049f9c99ec4Brian Paul pos1[0] = pos1[0] + half_width + bias; 1142a121e8e2289d2ca136f511c5a6ef049f9c99ec4Brian Paul pos2[0] = pos2[0] - half_width + bias; 1152a121e8e2289d2ca136f511c5a6ef049f9c99ec4Brian Paul pos3[0] = pos3[0] + half_width + bias; 116b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul if (pos0[1] < pos2[1]) { 117b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul /* top to bottom line */ 118b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos0[1] -= 0.5f; 119b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos1[1] -= 0.5f; 120b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos2[1] -= 0.5f; 121b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos3[1] -= 0.5f; 122b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul } 123b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul else { 124b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul /* bottom to top line */ 125b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos0[1] += 0.5f; 126b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos1[1] += 0.5f; 127b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos2[1] += 0.5f; 128b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul pos3[1] += 0.5f; 129b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul } 130b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul } 131b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 132b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul tri.det = header->det; /* only the sign matters */ 133b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul tri.v[0] = v0; 134b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul tri.v[1] = v2; 135b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul tri.v[2] = v3; 136b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul stage->next->tri( stage->next, &tri ); 137b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 138b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul tri.v[0] = v0; 139b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul tri.v[1] = v3; 140b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul tri.v[2] = v1; 141b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul stage->next->tri( stage->next, &tri ); 142b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul} 143b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 144b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 145b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paulstatic void wideline_flush( struct draw_stage *stage, unsigned flags ) 146b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul{ 147b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul stage->next->flush( stage->next, flags ); 148b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul} 149b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 150b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 151b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paulstatic void wideline_reset_stipple_counter( struct draw_stage *stage ) 152b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul{ 153b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul stage->next->reset_stipple_counter( stage->next ); 154b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul} 155b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 156b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 157b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paulstatic void wideline_destroy( struct draw_stage *stage ) 158b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul{ 159b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul draw_free_temp_verts( stage ); 160b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul FREE( stage ); 161b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul} 162b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 163b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 164b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paulstruct draw_stage *draw_wide_line_stage( struct draw_context *draw ) 165b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul{ 166b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul struct wideline_stage *wide = CALLOC_STRUCT(wideline_stage); 167b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 168b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul draw_alloc_temp_verts( &wide->stage, 4 ); 169b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 170b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul wide->stage.draw = draw; 171eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell wide->stage.name = "wide-line"; 172b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul wide->stage.next = NULL; 173a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell wide->stage.point = draw_pipe_passthrough_point; 174b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul wide->stage.line = wideline_line; 1753f6242d3e4d3ee61884a91a3eef4be8dfaadee3cBrian Paul wide->stage.tri = draw_pipe_passthrough_tri; 176b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul wide->stage.flush = wideline_flush; 177b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul wide->stage.reset_stipple_counter = wideline_reset_stipple_counter; 178b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul wide->stage.destroy = wideline_destroy; 179b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul 180b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul return &wide->stage; 181b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fbBrian Paul} 182