Exemplo n.º 1
0
void
_cogl_path_fill_nodes (CoglPath *path, CoglDrawFlags flags)
{
  gboolean needs_fallback = FALSE;
  CoglPipeline *pipeline = cogl_get_source ();

  _cogl_pipeline_foreach_layer_internal (pipeline,
                                         validate_layer_cb, &needs_fallback);
  if (needs_fallback)
    {
      _cogl_path_fill_nodes_with_clipped_rectangle (path);
      return;
    }

  _cogl_path_build_fill_attribute_buffer (path);

  _cogl_framebuffer_draw_indexed_attributes (cogl_get_draw_framebuffer (),
                                             pipeline,
                                             COGL_VERTICES_MODE_TRIANGLES,
                                             0, /* first_vertex */
                                             path->data->fill_vbo_n_indices,
                                             path->data->fill_vbo_indices,
                                             path->data->fill_attributes,
                                             COGL_PATH_N_ATTRIBUTES,
                                             flags);
}
static void
add_layer_declarations (CoglPipeline *pipeline,
                        CoglPipelineShaderState *shader_state)
{
  /* We always emit sampler uniforms in case there will be custom
   * layer snippets that want to sample arbitrary layers. */

  _cogl_pipeline_foreach_layer_internal (pipeline,
                                         add_layer_declaration_cb,
                                         shader_state);
}
Exemplo n.º 3
0
CoglBool
_cogl_pipeline_has_fragment_snippets (CoglPipeline *pipeline)
{
  CoglBool found_fragment_snippet = FALSE;

  if (_cogl_pipeline_has_non_layer_fragment_snippets (pipeline))
    return TRUE;

  _cogl_pipeline_foreach_layer_internal (pipeline,
                                         check_layer_has_fragment_snippet,
                                         &found_fragment_snippet);

  return found_fragment_snippet;
}
Exemplo n.º 4
0
void
_cogl_path_fill_nodes (CoglPath *path,
                       CoglFramebuffer *framebuffer,
                       CoglPipeline *pipeline,
                       CoglDrawFlags flags)
{
  if (path->data->path_nodes->len == 0)
    return;

  /* If the path is a simple rectangle then we can divert to using
     cogl_framebuffer_draw_rectangle which should be faster because it
     can go through the journal instead of uploading the geometry just
     for two triangles */
  if (path->data->is_rectangle && flags == 0)
    {
      float x_1, y_1, x_2, y_2;

      _cogl_path_get_bounds (path, &x_1, &y_1, &x_2, &y_2);
      cogl_framebuffer_draw_rectangle (framebuffer,
                                       pipeline,
                                       x_1, y_1,
                                       x_2, y_2);
    }
  else
    {
      CoglBool needs_fallback = FALSE;
      CoglPrimitive *primitive;

      _cogl_pipeline_foreach_layer_internal (pipeline,
                                             validate_layer_cb,
                                             &needs_fallback);
      if (needs_fallback)
        {
          _cogl_path_fill_nodes_with_clipped_rectangle (path,
                                                        framebuffer,
                                                        pipeline);
          return;
        }

      primitive = _cogl_path_get_fill_primitive (path);

      _cogl_primitive_draw (primitive,
                            framebuffer,
                            pipeline,
                            flags);
    }
}
Exemplo n.º 5
0
static CoglBool
_cogl_pipeline_fragend_fixed_end (CoglPipeline *pipeline,
                                  unsigned long pipelines_difference)
{
  int highest_unit_index = -1;
  int i;

  _COGL_GET_CONTEXT (ctx, FALSE);

  _cogl_pipeline_foreach_layer_internal (pipeline,
                                         get_highest_unit_index_cb,
                                         &highest_unit_index);

  /* Disable additional texture units that may have previously been in use.. */
  for (i = highest_unit_index + 1; i < ctx->texture_units->len; i++)
    _cogl_disable_texture_unit (i);

  return TRUE;
}
Exemplo n.º 6
0
void
_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
                                               GLuint shader_gl_handle,
                                               GLenum shader_gl_type,
                                               CoglPipeline *pipeline,
                                               GLsizei count_in,
                                               const char **strings_in,
                                               const GLint *lengths_in)
{
  const char *vertex_boilerplate;
  const char *fragment_boilerplate;

  const char **strings = g_alloca (sizeof (char *) * (count_in + 4));
  GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 4));
  char *version_string;
  int count = 0;

  int n_layers;

  vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE;
  fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE;

  version_string = g_strdup_printf ("#version %i\n\n",
                                    ctx->glsl_version_to_use);
  strings[count] = version_string;
  lengths[count++] = -1;

  if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_EMBEDDED) &&
      cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_3D))
    {
      static const char texture_3d_extension[] =
        "#extension GL_OES_texture_3D : enable\n";
      strings[count] = texture_3d_extension;
      lengths[count++] = sizeof (texture_3d_extension) - 1;
    }

  if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL))
    {
      static const char texture_3d_extension[] =
        "#extension GL_OES_EGL_image_external : require\n";
      strings[count] = texture_3d_extension;
      lengths[count++] = sizeof (texture_3d_extension) - 1;
    }

  if (shader_gl_type == GL_VERTEX_SHADER)
    {
      strings[count] = vertex_boilerplate;
      lengths[count++] = strlen (vertex_boilerplate);
    }
  else if (shader_gl_type == GL_FRAGMENT_SHADER)
    {
      strings[count] = fragment_boilerplate;
      lengths[count++] = strlen (fragment_boilerplate);
    }

  n_layers = cogl_pipeline_get_n_layers (pipeline);
  if (n_layers)
    {
      GString *layer_declarations = ctx->codegen_boilerplate_buffer;
      g_string_set_size (layer_declarations, 0);

      g_string_append_printf (layer_declarations,
                              "varying vec4 _cogl_tex_coord[%d];\n",
                              n_layers);

      if (shader_gl_type == GL_VERTEX_SHADER)
        {
          g_string_append_printf (layer_declarations,
                                  "uniform mat4 cogl_texture_matrix[%d];\n",
                                  n_layers);

          _cogl_pipeline_foreach_layer_internal (pipeline,
                                                 add_layer_vertex_boilerplate_cb,
                                                 layer_declarations);
        }
      else if (shader_gl_type == GL_FRAGMENT_SHADER)
        {
          _cogl_pipeline_foreach_layer_internal (pipeline,
                                                 add_layer_fragment_boilerplate_cb,
                                                 layer_declarations);
        }

      strings[count] = layer_declarations->str;
      lengths[count++] = -1; /* null terminated */
    }

  memcpy (strings + count, strings_in, sizeof (char *) * count_in);
  if (lengths_in)
    memcpy (lengths + count, lengths_in, sizeof (GLint) * count_in);
  else
    {
      int i;

      for (i = 0; i < count_in; i++)
        lengths[count + i] = -1; /* null terminated */
    }
  count += count_in;

  if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE)))
    {
      GString *buf = g_string_new (NULL);
      int i;

      g_string_append_printf (buf,
                              "%s shader:\n",
                              shader_gl_type == GL_VERTEX_SHADER ?
                              "vertex" : "fragment");
      for (i = 0; i < count; i++)
        if (lengths[i] != -1)
          g_string_append_len (buf, strings[i], lengths[i]);
        else
          g_string_append (buf, strings[i]);

      g_message ("%s", buf->str);

      g_string_free (buf, TRUE);
    }

  GE( ctx, glShaderSource (shader_gl_handle, count,
                           (const char **) strings, lengths) );

  g_free (version_string);
}
Exemplo n.º 7
0
static gboolean
_cogl_pipeline_fragend_fixed_end (CoglPipeline *pipeline,
                                  unsigned long pipelines_difference)
{
  int highest_unit_index = -1;
  int i;

  _COGL_GET_CONTEXT (ctx, FALSE);

  _cogl_pipeline_foreach_layer_internal (pipeline,
                                         get_highest_unit_index_cb,
                                         &highest_unit_index);

  /* Disable additional texture units that may have previously been in use.. */
  for (i = highest_unit_index + 1; i < ctx->texture_units->len; i++)
    _cogl_disable_texture_unit (i);

  if (pipelines_difference & COGL_PIPELINE_STATE_FOG)
    {
      CoglPipeline *authority =
        _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_FOG);
      CoglPipelineFogState *fog_state = &authority->big_state->fog_state;

      if (fog_state->enabled)
        {
          GLfloat fogColor[4];
          GLenum gl_mode = GL_LINEAR;

          fogColor[0] = cogl_color_get_red_float (&fog_state->color);
          fogColor[1] = cogl_color_get_green_float (&fog_state->color);
          fogColor[2] = cogl_color_get_blue_float (&fog_state->color);
          fogColor[3] = cogl_color_get_alpha_float (&fog_state->color);

          GE (ctx, glEnable (GL_FOG));

          GE (ctx, glFogfv (GL_FOG_COLOR, fogColor));

          if (ctx->driver == COGL_DRIVER_GLES1)
            switch (fog_state->mode)
              {
              case COGL_FOG_MODE_LINEAR:
                gl_mode = GL_LINEAR;
                break;
              case COGL_FOG_MODE_EXPONENTIAL:
                gl_mode = GL_EXP;
                break;
              case COGL_FOG_MODE_EXPONENTIAL_SQUARED:
                gl_mode = GL_EXP2;
                break;
              }
          /* TODO: support other modes for GLES2 */

          /* NB: GLES doesn't have glFogi */
          GE (ctx, glFogf (GL_FOG_MODE, gl_mode));
          GE (ctx, glHint (GL_FOG_HINT, GL_NICEST));

          GE (ctx, glFogf (GL_FOG_DENSITY, fog_state->density));
          GE (ctx, glFogf (GL_FOG_START, fog_state->z_near));
          GE (ctx, glFogf (GL_FOG_END, fog_state->z_far));
        }
      else
        GE (ctx, glDisable (GL_FOG));
    }

  return TRUE;
}