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); }
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); }
/* * 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; }