Ejemplo n.º 1
0
BOOL intersect_vis_rectangles( struct bitblt_coords *dst, struct bitblt_coords *src )
{
    RECT rect;

    /* intersect the rectangles */

    if ((src->width == dst->width) && (src->height == dst->height)) /* no stretching */
    {
        offset_rect( &src->visrect, dst->x - src->x, dst->y - src->y );
        if (!intersect_rect( &rect, &src->visrect, &dst->visrect )) return FALSE;
        src->visrect = dst->visrect = rect;
        offset_rect( &src->visrect, src->x - dst->x, src->y - dst->y );
    }
    else  /* stretching */
    {
        /* map source rectangle into destination coordinates */
        rect = src->visrect;
        offset_rect( &rect, -min( src->x, src->x + src->width + 1),
                     -min( src->y, src->y + src->height + 1) );
        rect.left   = dst->x + rect.left * dst->width / abs(src->width);
        rect.top    = dst->y + rect.top * dst->height / abs(src->height);
        rect.right  = dst->x + rect.right * dst->width / abs(src->width);
        rect.bottom = dst->y + rect.bottom * dst->height / abs(src->height);
        if (rect.left > rect.right) swap_ints( &rect.left, &rect.right );
        if (rect.top > rect.bottom) swap_ints( &rect.top, &rect.bottom );

        /* avoid rounding errors */
        rect.left--;
        rect.top--;
        rect.right++;
        rect.bottom++;
        if (!intersect_rect( &dst->visrect, &rect, &dst->visrect )) return FALSE;

        /* map destination rectangle back to source coordinates */
        rect = dst->visrect;
        offset_rect( &rect, -min( dst->x, dst->x + dst->width + 1),
                     -min( dst->y, dst->y + dst->height + 1) );
        rect.left   = src->x + rect.left * src->width / abs(dst->width);
        rect.top    = src->y + rect.top * src->height / abs(dst->height);
        rect.right  = src->x + rect.right * src->width / abs(dst->width);
        rect.bottom = src->y + rect.bottom * src->height / abs(dst->height);
        if (rect.left > rect.right) swap_ints( &rect.left, &rect.right );
        if (rect.top > rect.bottom) swap_ints( &rect.top, &rect.bottom );

        /* avoid rounding errors */
        rect.left--;
        rect.top--;
        rect.right++;
        rect.bottom++;
        if (!intersect_rect( &src->visrect, &rect, &src->visrect )) return FALSE;
    }
    return TRUE;
}
Ejemplo n.º 2
0
/***********************************************************************
 *           GetClipBox    (GDI32.@)
 */
INT WINAPI GetClipBox( HDC hdc, LPRECT rect )
{
    RECT visrect;
    INT ret;
    DC *dc = get_dc_ptr( hdc );
    if (!dc) return ERROR;

    update_dc( dc );
    if (get_dc_region( dc ))
    {
        ret = GetRgnBox( get_dc_region( dc ), rect );
    }
    else
    {
        ret = is_rect_empty( &dc->vis_rect ) ? ERROR : SIMPLEREGION;
        *rect = dc->vis_rect;
    }

    if (get_dc_device_rect( dc, &visrect ) && !intersect_rect( rect, rect, &visrect )) ret = NULLREGION;

    if (dc->layout & LAYOUT_RTL)
    {
        int tmp = rect->left;
        rect->left = rect->right - 1;
        rect->right = tmp - 1;
    }
    DPtoLP( hdc, (LPPOINT)rect, 2 );
    release_dc_ptr( dc );
    TRACE("%p => %d %s\n", hdc, ret, wine_dbgstr_rect( rect ));
    return ret;
}
Ejemplo n.º 3
0
static void recalc_children_invrgn(control_t *p_ctrl,
                                   BOOL is_add,
                                   const rect_t *p_rc_in_parent)
{
  rect_t rc_client, rc_frame, rc_parent;

  while(p_ctrl != NULL)
  {
    if(p_ctrl->attr != OBJ_ATTR_HIDDEN)
    {
      rc_parent = *p_rc_in_parent;
      ctrl_get_frame(p_ctrl, &rc_frame);

      if(intersect_rect(&rc_parent, &rc_parent, &rc_frame))
      {
        offset_rect(&rc_parent, (s16)(0 - p_ctrl->frame.left),
                    (s16)(0 - p_ctrl->frame.top));
        ctrl_get_client_rect(p_ctrl, &rc_client);
        update_invrgn_by_rect(&p_ctrl->invrgn_info,
                              is_add,
                              &rc_parent,
                              &rc_client);

        if(p_ctrl->p_child != NULL)
        {
          recalc_children_invrgn(p_ctrl->p_child, is_add, &rc_parent);
        }
      }
    }

    p_ctrl = p_ctrl->p_next;
  }
}
Ejemplo n.º 4
0
/***********************************************************************
 *           clip_visrect
 *
 * Clip a rectangle to the DC visible rect.
 */
BOOL clip_visrect( DC *dc, RECT *dst, const RECT *src )
{
    RECT clip;

    if (!clip_device_rect( dc, dst, src )) return FALSE;
    if (GetRgnBox( get_dc_region(dc), &clip )) return intersect_rect( dst, dst, &clip );
    return TRUE;
}
Ejemplo n.º 5
0
/***********************************************************************
 *           clip_device_rect
 *
 * Clip a rectangle to the whole DC surface.
 */
BOOL clip_device_rect( DC *dc, RECT *dst, const RECT *src )
{
    RECT clip;

    if (get_dc_device_rect( dc, &clip )) return intersect_rect( dst, src, &clip );
    *dst = *src;
    return TRUE;
}
Ejemplo n.º 6
0
Archivo: dc.c Proyecto: Barrell/wine
int clip_rect_to_dib( const dib_info *dib, RECT *rc )
{
    RECT rect;

    rect.left   = max( 0, -dib->rect.left );
    rect.top    = max( 0, -dib->rect.top );
    rect.right  = min( dib->rect.right, dib->width ) - dib->rect.left;
    rect.bottom = min( dib->rect.bottom, dib->height ) - dib->rect.top;
    if (is_rect_empty( &rect )) return 0;
    return intersect_rect( rc, &rect, rc );
}
Ejemplo n.º 7
0
static void update_invrgn_by_rect(crgn_info_t *p_invrgn,
                                  BOOL is_add,
                                  const rect_t *p_rc,
                                  const rect_t *p_client_rect)
{
  rect_t temp_rect;

  MT_ASSERT(p_invrgn != NULL && p_client_rect != NULL);

#ifdef MUTI_THREAD_SUPPORT
  os_mutex_lock(p_invrgn->lock);
#endif
  if(p_rc != NULL)
  {
    temp_rect = *p_rc;
    normalize_rect(&temp_rect);
    if(is_rect_covered(p_client_rect, &temp_rect))
    {
      if(is_add)
      {
        gdi_set_cliprgn(&p_invrgn->crgn, p_client_rect);
      }
      else
      {
        gdi_empty_cliprgn(&p_invrgn->crgn);
      }
    }
    else if(intersect_rect(&temp_rect, &temp_rect, p_client_rect))
    {
      if(is_add)
      {
        gdi_add_cliprect(&p_invrgn->crgn, &temp_rect);
      }
      else
      {
        gdi_subtract_cliprect(&p_invrgn->crgn, &temp_rect);
      }
    }
  }
  else
  {
    if(is_add)
    {
      gdi_set_cliprgn(&p_invrgn->crgn, p_client_rect);
    }
    else
    {
      gdi_empty_cliprgn(&p_invrgn->crgn);
    }
  }
#ifdef MUTI_THREAD_SUPPORT
  os_mutex_unlock(p_invrgn->lock);
#endif
}
Ejemplo n.º 8
0
Archivo: dc.c Proyecto: Barrell/wine
int get_clipped_rects( const dib_info *dib, const RECT *rc, HRGN clip, struct clipped_rects *clip_rects )
{
    const WINEREGION *region;
    RECT rect, *out = clip_rects->buffer;
    int i;

    init_clipped_rects( clip_rects );

    rect.left   = max( 0, -dib->rect.left );
    rect.top    = max( 0, -dib->rect.top );
    rect.right  = min( dib->rect.right, dib->width ) - dib->rect.left;
    rect.bottom = min( dib->rect.bottom, dib->height ) - dib->rect.top;
    if (is_rect_empty( &rect )) return 0;
    if (rc && !intersect_rect( &rect, &rect, rc )) return 0;

    if (!clip)
    {
        *out = rect;
        clip_rects->count = 1;
        return 1;
    }

    if (!(region = get_wine_region( clip ))) return 0;

    for (i = 0; i < region->numRects; i++)
    {
        if (region->rects[i].top >= rect.bottom) break;
        if (!intersect_rect( out, &rect, &region->rects[i] )) continue;
        out++;
        if (out == &clip_rects->buffer[sizeof(clip_rects->buffer) / sizeof(RECT)])
        {
            clip_rects->rects = HeapAlloc( GetProcessHeap(), 0, region->numRects * sizeof(RECT) );
            if (!clip_rects->rects) return 0;
            memcpy( clip_rects->rects, clip_rects->buffer, (out - clip_rects->buffer) * sizeof(RECT) );
            out = clip_rects->rects + (out - clip_rects->buffer);
        }
    }
    release_wine_region( clip );
    clip_rects->count = out - clip_rects->rects;
    return clip_rects->count;
}
Ejemplo n.º 9
0
Archivo: dc.c Proyecto: Barrell/wine
void dibdrv_set_window_surface( DC *dc, struct window_surface *surface )
{
    char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
    BITMAPINFO *info = (BITMAPINFO *)buffer;
    RECT rect;
    void *bits;
    PHYSDEV windev;
    struct windrv_physdev *physdev;
    struct dibdrv_physdev *dibdrv;

    TRACE( "%p %p\n", dc->hSelf, surface );

    windev = pop_dc_driver( dc, &window_driver );

    if (surface)
    {
        if (windev) push_dc_driver( &dc->physDev, windev, windev->funcs );
        else
        {
            if (!window_driver.pCreateDC( &dc->physDev, NULL, NULL, NULL, NULL )) return;
            windev = find_dc_driver( dc, &window_driver );
        }

        physdev = get_windrv_physdev( windev );
        window_surface_add_ref( surface );
        if (physdev->surface) window_surface_release( physdev->surface );
        physdev->surface = surface;

        dibdrv = physdev->dibdrv;
        bits = surface->funcs->get_info( surface, info );
        init_dib_info_from_bitmapinfo( &dibdrv->dib, info, bits );
        /* clip the device rect to the surface */
        rect = surface->rect;
        offset_rect( &rect, dc->device_rect.left, dc->device_rect.top );
        intersect_rect( &dc->device_rect, &dc->device_rect, &rect );
        dibdrv->dib.rect = dc->vis_rect;
        offset_rect( &dibdrv->dib.rect, -rect.left, -rect.top );
        dibdrv->bounds = surface->funcs->get_bounds( surface );
        DC_InitDC( dc );
    }
    else if (windev)
    {
        dib_driver.pDeleteDC( pop_dc_driver( dc, &dib_driver ));
        windev->funcs->pDeleteDC( windev );
        DC_InitDC( dc );
    }
}
Ejemplo n.º 10
0
/***********************************************************************
 *           RectVisible    (GDI32.@)
 */
BOOL WINAPI RectVisible( HDC hdc, const RECT* rect )
{
    RECT tmpRect, visrect;
    BOOL ret;
    DC *dc = get_dc_ptr( hdc );
    if (!dc) return FALSE;
    TRACE("%p %s\n", hdc, wine_dbgstr_rect( rect ));

    tmpRect = *rect;
    lp_to_dp( dc, (POINT *)&tmpRect, 2 );
    order_rect( &tmpRect );

    update_dc( dc );
    ret = (!get_dc_device_rect( dc, &visrect ) || intersect_rect( &visrect, &visrect, &tmpRect ));
    if (ret && get_dc_region( dc )) ret = RectInRegion( get_dc_region( dc ), &tmpRect );
    release_dc_ptr( dc );
    return ret;
}
Ejemplo n.º 11
0
Archivo: dc.c Proyecto: Barrell/wine
void add_clipped_bounds( dibdrv_physdev *dev, const RECT *rect, HRGN clip )
{
    const WINEREGION *region;
    RECT rc;

    if (!dev->bounds) return;
    if (clip)
    {
        if (!(region = get_wine_region( clip ))) return;
        if (!rect) rc = region->extents;
        else intersect_rect( &rc, rect, &region->extents );
        release_wine_region( clip );
    }
    else rc = *rect;

    if (is_rect_empty( &rc )) return;
    offset_rect( &rc, dev->dib.rect.left, dev->dib.rect.top );
    add_bounds_rect( dev->bounds, &rc );
}
bool intersect_rect_ex(CvRect* r1, CvRect* r2, CvRect* r3)
{
  bool intersects = intersect_rect(r1, r2);
  
  if (intersects)
  {
    r3->x = std::max(r1->x, r2->x);
    r3->y = std::max(r1->y, r2->y);
    r3->width = std::min(r1->x + r1->width, r2->x + r2->width);
    r3->height = std::min(r1->y + r1->height, r2->y + r2->height);
  }
  else
  {
    r3->x = 0;
    r3->y = 0;
    r3->width = 0;
    r3->height = 0;
  }
  return intersects;
}
Ejemplo n.º 13
0
static RET_CODE on_cbox_paint(control_t *p_ctrl, u16 msg, u32 para1, u32 para2)
{
  rect_t rc_client, rc_list, rc_affected;
  hdc_t parent_dc = (hdc_t)(para2);

  control_t *p_list = _cbox_get_droplist(p_ctrl);

  if((p_ctrl->priv_attr & CBOX_STATUS_MASK) == CBOX_STATUS_LIST)
  {
    if(p_list != NULL)
    {
      ctrl_get_frame(p_ctrl, &rc_client);
      ctrl_client2screen(p_ctrl, &rc_client);

      ctrl_get_frame(p_list, &rc_list);
      ctrl_client2screen(p_list, &rc_list);

      if(intersect_rect(&rc_affected, &rc_client, &rc_list))
      {
        if(ctrl_screen2client(p_list, &rc_affected))
        {
          ctrl_subtract_rect_from_invrgn(p_ctrl, &rc_affected);
        }
      }
    }
  }

  //reset content.
  cbox_get_content(p_ctrl, _cbox_common_get_focus(p_ctrl));

  ctrl_default_proc(p_ctrl, msg, para1, para2);

  //this bar isn't list's child, when parent_dc isn't 0,
  //parent control will draw bar
  if(parent_dc == HDC_INVALID)
  {
    _cbox_draw_droplist(p_ctrl);
  }

  return SUCCESS;
}
Ejemplo n.º 14
0
void radeonRecalcScissorRects(radeonContextPtr radeon)
{
	drm_clip_rect_t *out;
	int i;

	/* Grow cliprect store?
	 */
	if (radeon->state.scissor.numAllocedClipRects < radeon->numClipRects) {
		while (radeon->state.scissor.numAllocedClipRects <
		       radeon->numClipRects) {
			radeon->state.scissor.numAllocedClipRects += 1;	/* zero case */
			radeon->state.scissor.numAllocedClipRects *= 2;
		}

		if (radeon->state.scissor.pClipRects)
			FREE(radeon->state.scissor.pClipRects);

		radeon->state.scissor.pClipRects =
		    MALLOC(radeon->state.scissor.numAllocedClipRects *
			   sizeof(drm_clip_rect_t));

		if (radeon->state.scissor.pClipRects == NULL) {
			radeon->state.scissor.numAllocedClipRects = 0;
			return;
		}
	}

	out = radeon->state.scissor.pClipRects;
	radeon->state.scissor.numClipRects = 0;

	for (i = 0; i < radeon->numClipRects; i++) {
		if (intersect_rect(out,
				   &radeon->pClipRects[i],
				   &radeon->state.scissor.rect)) {
			radeon->state.scissor.numClipRects++;
			out++;
		}
	}
}
Ejemplo n.º 15
0
inline void t_sorted_clip_list::intersect( t_quadtree_node& parent_node, t_screen_rect const & query_area , t_rect_list & result, int depth)
{

	//to find all the rects that intersect with the given rectangle, we walk the tree 

	//-if the query_area contains the full extent, then return the entire list of rects
	//-check the query_area against each node starting with the parent.
	//-if the query_area interects or is contained wihin a child area walk down that
	//		childs nodes
	//			a)if intersect, walk down child node
	//			b)if contained, walk only down this child node, all others can be ignored
	
	intersect_rect( parent_node, query_area, result );

	depth++;

	if (depth > m_sub_division_level)
		return;

	//query for containment ( early out )///////////////////////////////////////////////
	//stop search if containment is found.
	
	if (m_quadtree_array[parent_node.node_a].area.contains( query_area ) == true)
	{
		intersect( m_quadtree_array[parent_node.node_a], query_area, result, depth );
		return;
	}
	
	if (m_quadtree_array[parent_node.node_b].area.contains( query_area ) == true)
	{
		intersect( m_quadtree_array[parent_node.node_b], query_area, result, depth );
		return;
	}
	
	if (m_quadtree_array[parent_node.node_c].area.contains( query_area ) == true)
	{
		intersect( m_quadtree_array[parent_node.node_c], query_area, result, depth );
		return;
	}
	
	if (m_quadtree_array[parent_node.node_d].area.contains( query_area ) == true)
	{
		intersect( m_quadtree_array[parent_node.node_d], query_area, result, depth );
		return;
	}

	//query each child_node/////////////////////////////////////////////////////////////

	if (::intersect(m_quadtree_array[parent_node.node_a].area, query_area)==true)
	{
		intersect( m_quadtree_array[parent_node.node_a], query_area, result, depth );
	}
	
	if (::intersect(m_quadtree_array[parent_node.node_b].area, query_area)==true)
	{	
		intersect( m_quadtree_array[parent_node.node_b], query_area, result, depth );
	}
		
	if (::intersect(m_quadtree_array[parent_node.node_c].area, query_area)==true)
	{
		intersect( m_quadtree_array[parent_node.node_c], query_area, result, depth );
	}
			
	if (::intersect(m_quadtree_array[parent_node.node_d].area, query_area)==true)
	{
		intersect( m_quadtree_array[parent_node.node_d], query_area, result, depth );
	}

	return;
}
Ejemplo n.º 16
0
void mgaFlushVerticesLocked( mgaContextPtr mmesa )
{
   XF86DRIClipRectPtr pbox = mmesa->pClipRects;
   int nbox = mmesa->numClipRects;
   drmBufPtr buffer = mmesa->vertex_dma_buffer;
   drmMGAVertex vertex;
   int i;

   mmesa->vertex_dma_buffer = 0;

   if (!buffer)
      return;

   if (mmesa->dirty_cliprects & mmesa->draw_buffer)
      mgaUpdateRects( mmesa, mmesa->draw_buffer );

   if (mmesa->dirty & ~MGA_UPLOAD_CLIPRECTS)
      mgaEmitHwStateLocked( mmesa );

   /* FIXME: Workaround bug in kernel module.
    */
   mmesa->sarea->dirty |= MGA_UPLOAD_CONTEXT;

   if (!nbox)
      buffer->used = 0;

   if (nbox >= MGA_NR_SAREA_CLIPRECTS)
      mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;

#if 0
   if (!buffer->used || !(mmesa->dirty & MGA_UPLOAD_CLIPRECTS))
   {
      if (nbox == 1)
	 mmesa->sarea->nbox = 0;
      else
	 mmesa->sarea->nbox = nbox;

      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)
	 fprintf(stderr, "Firing vertex -- case a nbox %d\n", nbox);

      vertex.idx = buffer->idx;
      vertex.used = buffer->used;
      vertex.discard = 1;
      drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX, 
                       &vertex, sizeof(drmMGAVertex) );

      age_mmesa(mmesa, mmesa->sarea->last_enqueue);
   }
   else
#endif
   {
      for (i = 0 ; i < nbox ; )
      {
	 int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, nbox);
	 XF86DRIClipRectPtr b = mmesa->sarea->boxes;
	 int discard = 0;

	 if (mmesa->scissor) {
	    mmesa->sarea->nbox = 0;

	    for ( ; i < nr ; i++) {
	       *b = pbox[i];
	       if (intersect_rect(b, b, &mmesa->scissor_rect)) {
		  mmesa->sarea->nbox++;
		  b++;
	       }
	    }

	    /* Culled?
	     */
	    if (!mmesa->sarea->nbox) {
	       if (nr < nbox) continue;
	       buffer->used = 0;
	    }
	 } else {
	    mmesa->sarea->nbox = nr - i;
	    for ( ; i < nr ; i++)
	       *b++ = pbox[i];
	 }

	 /* Finished with the buffer?
	  */
	 if (nr == nbox)
	    discard = 1;

	 mmesa->sarea->dirty |= MGA_UPLOAD_CLIPRECTS;

         vertex.idx = buffer->idx;
         vertex.used = buffer->used;
         vertex.discard = discard;
         drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX, 
                          &vertex, sizeof(drmMGAVertex) );

	 age_mmesa(mmesa, mmesa->sarea->last_enqueue);
      }
   }

   /* Do we really need to do this ? */
#ifdef __i386__
   if ( __break_vertex ) {
      __asm__ __volatile__ ( "int $3" );
   }
#endif

   mmesa->dirty &= ~MGA_UPLOAD_CLIPRECTS;
}
Ejemplo n.º 17
0
static gboolean
intersect_box (GimpVector3        scale,
	       GimpVector3        viewp,
	       GimpVector3        dir,
	       FaceIntersectInfo *face_intersect)
{
  GimpVector3        v, d, tmp, axis[3];
  FaceIntersectInfo  face_tmp;
  gboolean           result = FALSE;
  gfloat             m[16];
  gint               i = 0;

  gimp_vector3_set (&axis[0], 1.0, 0.0, 0.0);
  gimp_vector3_set (&axis[1], 0.0, 1.0, 0.0);
  gimp_vector3_set (&axis[2], 0.0, 0.0, 1.0);

  /* Front side */
  /* ========== */

  if (intersect_rect (scale.x, scale.y, scale.z / 2.0,
		      viewp, dir, &face_intersect[i]) == TRUE)
    {
      face_intersect[i].face = 0;
      gimp_vector3_set (&face_intersect[i++].n, 0.0, 0.0, 1.0);
      result = TRUE;
    }

  /* Back side */
  /* ========= */

  if (intersect_rect (scale.x, scale.y, -scale.z / 2.0,
		      viewp, dir, &face_intersect[i]) == TRUE)
    {
      face_intersect[i].face = 1;
      face_intersect[i].u = 1.0 - face_intersect[i].u;
      gimp_vector3_set (&face_intersect[i++].n, 0.0, 0.0, -1.0);
      result = TRUE;
    }

  /* Check if we've found the two possible intersection points */
  /* ========================================================= */

  if (i < 2)
    {
      /* Top: Rotate viewpoint and direction into rectangle's local coordinate system */
      /* ============================================================================ */

      rotatemat (90, &axis[0], m);
      vecmulmat (&v, &viewp, m);
      vecmulmat (&d, &dir, m);

      if (intersect_rect (scale.x, scale.z, scale.y / 2.0,
			  v, d, &face_intersect[i]) == TRUE)
        {
          face_intersect[i].face = 2;

          transpose_mat (m);
          vecmulmat(&tmp, &face_intersect[i].s, m);
          face_intersect[i].s = tmp;

          gimp_vector3_set (&face_intersect[i++].n, 0.0, -1.0, 0.0);
          result = TRUE;
        }
    }

  /* Check if we've found the two possible intersection points */
  /* ========================================================= */

  if (i < 2)
    {
      /* Bottom: Rotate viewpoint and direction into rectangle's local coordinate system */
      /* =============================================================================== */

      rotatemat (90, &axis[0], m);
      vecmulmat (&v, &viewp, m);
      vecmulmat (&d, &dir, m);

      if (intersect_rect (scale.x, scale.z, -scale.y / 2.0,
			  v, d, &face_intersect[i]) == TRUE)
        {
          face_intersect[i].face = 3;

          transpose_mat (m);

          vecmulmat (&tmp, &face_intersect[i].s, m);
          face_intersect[i].s = tmp;

          face_intersect[i].v = 1.0 - face_intersect[i].v;

          gimp_vector3_set (&face_intersect[i++].n, 0.0, 1.0, 0.0);

          result = TRUE;
        }
    }

  /* Check if we've found the two possible intersection points */
  /* ========================================================= */

  if (i < 2)
    {
      /* Left side: Rotate viewpoint and direction into rectangle's local coordinate system */
      /* ================================================================================== */

      rotatemat (90, &axis[1], m);
      vecmulmat (&v, &viewp, m);
      vecmulmat (&d, &dir, m);

      if (intersect_rect (scale.z, scale.y, scale.x / 2.0,
			  v, d, &face_intersect[i]) == TRUE)
        {
          face_intersect[i].face = 4;

          transpose_mat (m);
          vecmulmat (&tmp, &face_intersect[i].s, m);
          face_intersect[i].s = tmp;

          gimp_vector3_set (&face_intersect[i++].n, 1.0, 0.0, 0.0);
          result = TRUE;
        }
    }

  /* Check if we've found the two possible intersection points */
  /* ========================================================= */

  if (i < 2)
    {
      /* Right side: Rotate viewpoint and direction into rectangle's local coordinate system */
      /* =================================================================================== */

      rotatemat (90, &axis[1], m);
      vecmulmat (&v, &viewp, m);
      vecmulmat (&d, &dir, m);

      if (intersect_rect (scale.z, scale.y, -scale.x / 2.0,
			  v, d, &face_intersect[i]) == TRUE)
        {
          face_intersect[i].face = 5;

          transpose_mat (m);
          vecmulmat (&tmp, &face_intersect[i].s, m);

          face_intersect[i].u = 1.0 - face_intersect[i].u;

          gimp_vector3_set (&face_intersect[i++].n, -1.0, 0.0, 0.0);
          result = TRUE;
        }
    }

  /* Sort intersection points */
  /* ======================== */

  if (face_intersect[0].t > face_intersect[1].t)
    {
      face_tmp = face_intersect[0];
      face_intersect[0] = face_intersect[1];
      face_intersect[1] = face_tmp;
    }

  return result;
}
Ejemplo n.º 18
0
/*
 * Examine XF86 cliprect list and scissor state to recompute our
 * cliprect list.
 */
void tdfxUpdateClipping( GLcontext *ctx )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
   __DRIdrawable *dPriv = fxMesa->driDrawable;

   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "%s()\n", __FUNCTION__ );
   }

   assert(ctx);
   assert(fxMesa);
   assert(dPriv);

   if ( dPriv->x != fxMesa->x_offset || dPriv->y != fxMesa->y_offset ||
	dPriv->w != fxMesa->width || dPriv->h != fxMesa->height ) {
      fxMesa->x_offset = dPriv->x;
      fxMesa->y_offset = dPriv->y;
      fxMesa->width = dPriv->w;
      fxMesa->height = dPriv->h;
      fxMesa->y_delta =
	 fxMesa->screen_height - fxMesa->y_offset - fxMesa->height;
      tdfxUpdateViewport( ctx );
   }

   if (fxMesa->scissoredClipRects && fxMesa->pClipRects) {
      free(fxMesa->pClipRects);
   }

   if (ctx->Scissor.Enabled) {
      /* intersect OpenGL scissor box with all cliprects to make a new
       * list of cliprects.
       */
      drm_clip_rect_t scissor;
      int x1 = ctx->Scissor.X + fxMesa->x_offset;
      int y1 = fxMesa->screen_height - fxMesa->y_delta
             - ctx->Scissor.Y - ctx->Scissor.Height;
      int x2 = x1 + ctx->Scissor.Width;
      int y2 = y1 + ctx->Scissor.Height;
      scissor.x1 = MAX2(x1, 0);
      scissor.y1 = MAX2(y1, 0);
      scissor.x2 = MAX2(x2, 0);
      scissor.y2 = MAX2(y2, 0);

      assert(scissor.x2 >= scissor.x1);
      assert(scissor.y2 >= scissor.y1);

      fxMesa->pClipRects = malloc(dPriv->numClipRects
                                  * sizeof(drm_clip_rect_t));
      if (fxMesa->pClipRects) {
         int i;
         fxMesa->numClipRects = 0;
         for (i = 0; i < dPriv->numClipRects; i++) {
            if (intersect_rect(&fxMesa->pClipRects[fxMesa->numClipRects],
                               &scissor, &dPriv->pClipRects[i])) {
               fxMesa->numClipRects++;
            }
         }
         fxMesa->scissoredClipRects = GL_TRUE;
      }
      else {
         /* out of memory, forgo scissor */
         fxMesa->numClipRects = dPriv->numClipRects;
         fxMesa->pClipRects = dPriv->pClipRects;
         fxMesa->scissoredClipRects = GL_FALSE;
      }
   }
   else {
      fxMesa->numClipRects = dPriv->numClipRects;
      fxMesa->pClipRects = dPriv->pClipRects;
      fxMesa->scissoredClipRects = GL_FALSE;
   }

   fxMesa->dirty |= TDFX_UPLOAD_CLIP;
}
Ejemplo n.º 19
0
void i810FlushPrimsLocked( i810ContextPtr imesa )
{
   drm_clip_rect_t *pbox = imesa->pClipRects;
   int nbox = imesa->numClipRects;
   drmBufPtr buffer = imesa->vertex_buffer;
   I810SAREAPtr sarea = imesa->sarea;
   drmI810Vertex vertex;
   int i;
	  
   if (I810_DEBUG & DEBUG_STATE)
      i810PrintDirty( __FUNCTION__, imesa->dirty );
   
   if (imesa->dirty)
      emit_state( imesa );

   vertex.idx = buffer->idx;
   vertex.used = imesa->vertex_low;
   vertex.discard = 0;
   sarea->vertex_prim = imesa->hw_primitive;

   if (!nbox) {
      vertex.used = 0;
   }
   else if (nbox > I810_NR_SAREA_CLIPRECTS) {      
      imesa->upload_cliprects = GL_TRUE;
   }

   if (!nbox || !imesa->upload_cliprects) 
   {
      if (nbox == 1) 
	 sarea->nbox = 0;
      else
	 sarea->nbox = nbox;

      vertex.discard = 1;	
      drmCommandWrite(imesa->driFd, DRM_I810_VERTEX,
                      &vertex, sizeof(drmI810Vertex));
      age_imesa(imesa, sarea->last_enqueue);
   }  
   else 
   {
      for (i = 0 ; i < nbox ; )
      {
	 int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, nbox);
	 drm_clip_rect_t *b = (drm_clip_rect_t *)sarea->boxes;

	 if (imesa->scissor) {
	    sarea->nbox = 0;
	 
	    for ( ; i < nr ; i++) {
	       b->x1 = pbox[i].x1 - imesa->drawX;
	       b->y1 = pbox[i].y1 - imesa->drawY;
	       b->x2 = pbox[i].x2 - imesa->drawX;
	       b->y2 = pbox[i].y2 - imesa->drawY;

	       if (intersect_rect(b, b, &imesa->scissor_rect)) {
		  sarea->nbox++;
		  b++;
	       }
	    }

	    /* Culled?
	     */
	    if (!sarea->nbox) {
	       if (nr < nbox) continue;
	       vertex.used = 0;
	    }
	 } else {
	    sarea->nbox = nr - i;
	    for ( ; i < nr ; i++, b++) {
	       b->x1 = pbox[i].x1 - imesa->drawX;
	       b->y1 = pbox[i].y1 - imesa->drawY;
	       b->x2 = pbox[i].x2 - imesa->drawX;
	       b->y2 = pbox[i].y2 - imesa->drawY;
	    }
	 }
	 
	 /* Finished with the buffer?
	  */
	 if (nr == nbox) 
	    vertex.discard = 1;

	 drmCommandWrite(imesa->driFd, DRM_I810_VERTEX,
                         &vertex, sizeof(drmI810Vertex));
	 age_imesa(imesa, imesa->sarea->last_enqueue);
      }
   }

   /* Reset imesa vars:
    */
   imesa->vertex_buffer = 0;
   imesa->vertex_addr = 0;
   imesa->vertex_low = 0;
   imesa->vertex_high = 0;
   imesa->vertex_last_prim = 0;
   imesa->dirty = 0;
   imesa->upload_cliprects = GL_FALSE;
}