add support for sprite texcoord modes
authorBrian <brian.paul@tungstengraphics.com>
Mon, 22 Oct 2007 18:10:30 +0000 (12:10 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Mon, 22 Oct 2007 18:10:30 +0000 (12:10 -0600)
src/mesa/pipe/draw/draw_wide_prims.c
src/mesa/pipe/p_defines.h
src/mesa/pipe/p_state.h
src/mesa/state_tracker/st_atom_rasterizer.c

index 0d02e70814ecf790b777dcf15f7673ad135efd42..917944a6110d6eb59932e67fa9ba7614040595ae 100644 (file)
@@ -40,7 +40,8 @@ struct wide_stage {
    float half_line_width;
    float half_point_size;
 
-   uint texcoord[PIPE_MAX_SHADER_OUTPUTS];
+   uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS];
+   uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS];
    uint num_texcoords;
 };
 
@@ -123,16 +124,26 @@ static void wide_line( struct draw_stage *stage,
 }
 
 
+/**
+ * Set the vertex texcoords for sprite mode.
+ * Coords may be left untouched or set to a right-side-up or upside-down
+ * orientation.
+ */
 static void set_texcoords(const struct wide_stage *wide,
                           struct vertex_header *v, const float tc[4])
 {
    uint i;
    for (i = 0; i < wide->num_texcoords; i++) {
-      uint j = wide->texcoord[i];
-      v->data[j][0] = tc[0];
-      v->data[j][1] = tc[1];
-      v->data[j][2] = tc[2];
-      v->data[j][3] = tc[3];
+      if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) {
+         uint j = wide->texcoord_slot[i];
+         v->data[j][0] = tc[0];
+         if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT)
+            v->data[j][1] = 1.0 - tc[1];
+         else
+            v->data[j][1] = tc[1];
+         v->data[j][2] = tc[2];
+         v->data[j][3] = tc[3];
+      }
    }
 }
 
@@ -230,7 +241,9 @@ static void wide_begin( struct draw_stage *stage )
       uint i, j = 0;
       for (i = 0; i < vs->state->num_outputs; i++) {
          if (vs->state->output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) {
-            wide->texcoord[j++] = i;
+            wide->texcoord_slot[j] = i;
+            wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j];
+            j++;
          }
       }
       wide->num_texcoords = j;
index d336f8399808fdf15ae036a993be8c165844dd4e..9281d40bd3b5504e24d21e331fe75ff5bc9a0961 100644 (file)
 #define PIPE_QUERY_TYPES                 3
 
 
+/**
+ * Point sprite coord modes
+ */
+#define PIPE_SPRITE_COORD_NONE       0
+#define PIPE_SPRITE_COORD_UPPER_LEFT 1
+#define PIPE_SPRITE_COORD_LOWER_LEFT 2
+
 #endif
index fd3f4f22b9e5783697ed36ec5a728c1d4210666a..ecbcbd098afa0e19c9d8f71da724f5e1351532f8 100644 (file)
@@ -96,6 +96,7 @@ struct pipe_rasterizer_state
    float point_size;           /**< used when no per-vertex size */
    float offset_units;
    float offset_scale;
+   ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */
 };
 
 
index 9fbd7dc09ef625d0ae4abeba02f40cea4ad5013c..9f857e28375c74a3b08e6ae62871da9d1eee42a9 100644 (file)
@@ -74,6 +74,7 @@ static void update_raster_state( struct st_context *st )
    GLcontext *ctx = st->ctx;
    struct pipe_rasterizer_state raster;
    const struct cso_rasterizer *cso;
+   uint i;
 
    memset(&raster, 0, sizeof(raster));
    
@@ -189,6 +190,17 @@ static void update_raster_state( struct st_context *st )
    raster.point_size = ctx->Point.Size;
    raster.point_smooth = ctx->Point.SmoothFlag;
    raster.point_sprite = ctx->Point.PointSprite;
+   for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
+      if (ctx->Point.CoordReplace[i]) {
+         if (ctx->Point.SpriteOrigin == GL_UPPER_LEFT)
+            raster.sprite_coord_mode[i] = PIPE_SPRITE_COORD_UPPER_LEFT;
+         else 
+            raster.sprite_coord_mode[i] = PIPE_SPRITE_COORD_LOWER_LEFT;
+      }
+      else {
+         raster.sprite_coord_mode[i] = PIPE_SPRITE_COORD_NONE;
+      }
+   }
 
    /* _NEW_LINE
     */