static CoglTransformResult
_cogl_texture_pixmap_x11_transform_quad_coords_to_gl (CoglTexture *tex,
                                                      float       *coords)
{
  CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
  CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);

  /* Forward on to the child texture */
  return _cogl_texture_transform_quad_coords_to_gl (child_tex, coords);
}
Beispiel #2
0
static CoglTransformResult
_cogl_sub_texture_transform_quad_coords_to_gl (CoglTexture *tex,
                                               float *coords)
{
  CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);
  int i;

  /* We can't support repeating with this method. In this case
     cogl-primitives will resort to manual repeating */
  for (i = 0; i < 4; i++)
    if (coords[i] < 0.0f || coords[i] > 1.0f)
      return COGL_TRANSFORM_SOFTWARE_REPEAT;

  _cogl_sub_texture_map_quad (sub_tex, coords);

  return _cogl_texture_transform_quad_coords_to_gl (sub_tex->full_texture,
                                                    coords);
}
Beispiel #3
0
/*
 * Validate the texture coordinates for this rectangle.
 */
static CoglBool
validate_tex_coords_cb (CoglPipeline *pipeline,
                        int layer_index,
                        void *user_data)
{
  ValidateTexCoordsState *state = user_data;
  CoglTexture *texture;
  const float *in_tex_coords;
  float *out_tex_coords;
  float default_tex_coords[4] = {0.0, 0.0, 1.0, 1.0};
  CoglTransformResult transform_result;

  state->i++;

  /* FIXME: we should be able to avoid this copying when no
   * transform is required by the texture backend and the user
   * has supplied enough coordinates for all the layers.
   */

  /* If the user didn't supply texture coordinates for this layer
     then use the default coords */
  if (state->i >= state->user_tex_coords_len / 4)
    in_tex_coords = default_tex_coords;
  else
    in_tex_coords = &state->user_tex_coords[state->i * 4];

  out_tex_coords = &state->final_tex_coords[state->i * 4];

  memcpy (out_tex_coords, in_tex_coords, sizeof (float) * 4);

  texture = cogl_pipeline_get_layer_texture (pipeline, layer_index);

  /* NB: NULL textures are handled by _cogl_pipeline_flush_gl_state */
  if (!texture)
    return TRUE;

  /* Convert the texture coordinates to GL.
   */
  transform_result =
    _cogl_texture_transform_quad_coords_to_gl (texture,
                                               out_tex_coords);
  /* If the texture has waste or we are using GL_TEXTURE_RECT we
   * can't handle texture repeating so we can't use the layer if
   * repeating is required.
   *
   * NB: We already know that no texture matrix is being used if the
   * texture doesn't support hardware repeat.
   */
  if (transform_result == COGL_TRANSFORM_SOFTWARE_REPEAT)
    {
      if (state->i == 0)
        {
          if (state->n_layers > 1)
            {
              static CoglBool warning_seen = FALSE;
              if (!warning_seen)
                g_warning ("Skipping layers 1..n of your material since "
                           "the first layer doesn't support hardware "
                           "repeat (e.g. because of waste or use of "
                           "GL_TEXTURE_RECTANGLE_ARB) and you supplied "
                           "texture coordinates outside the range [0,1]."
                           "Falling back to software repeat assuming "
                           "layer 0 is the most important one keep");
              warning_seen = TRUE;
            }

          if (state->override_pipeline)
            cogl_object_unref (state->override_pipeline);
          state->needs_multiple_primitives = TRUE;
          return FALSE;
        }
      else
        {
          static CoglBool warning_seen = FALSE;
          if (!warning_seen)
            g_warning ("Skipping layer %d of your material "
                       "since you have supplied texture coords "
                       "outside the range [0,1] but the texture "
                       "doesn't support hardware repeat (e.g. "
                       "because of waste or use of "
                       "GL_TEXTURE_RECTANGLE_ARB). This isn't "
                       "supported with multi-texturing.", state->i);
          warning_seen = TRUE;

          cogl_pipeline_set_layer_texture (pipeline, layer_index, NULL);
        }
    }

  /* By default WRAP_MODE_AUTOMATIC becomes to CLAMP_TO_EDGE. If
     the texture coordinates need repeating then we'll override
     this to GL_REPEAT. Otherwise we'll leave it at CLAMP_TO_EDGE
     so that it won't blend in pixels from the opposite side when
     the full texture is drawn with GL_LINEAR filter mode */
  if (transform_result == COGL_TRANSFORM_HARDWARE_REPEAT)
    {
      if (cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index) ==
          COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
        {
          if (!state->override_pipeline)
            state->override_pipeline = cogl_pipeline_copy (pipeline);
          cogl_pipeline_set_layer_wrap_mode_s (state->override_pipeline,
                                               layer_index,
                                               COGL_PIPELINE_WRAP_MODE_REPEAT);
        }
      if (cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index) ==
          COGL_PIPELINE_WRAP_MODE_AUTOMATIC)
        {
          if (!state->override_pipeline)
            state->override_pipeline = cogl_pipeline_copy (pipeline);
          cogl_pipeline_set_layer_wrap_mode_t (state->override_pipeline,
                                               layer_index,
                                               COGL_PIPELINE_WRAP_MODE_REPEAT);
        }
    }

  return TRUE;
}