static CoglBool _cogl_pipeline_progend_fixed_start (CoglPipeline *pipeline) { _COGL_GET_CONTEXT (ctx, FALSE); if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FIXED))) return FALSE; if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED)) return FALSE; /* Vertex snippets are only supported in the GLSL fragend */ if (_cogl_pipeline_has_vertex_snippets (pipeline)) return FALSE; /* Fragment snippets are only supported in the GLSL fragend */ if (_cogl_pipeline_has_fragment_snippets (pipeline)) return FALSE; /* If there is a user program then the appropriate backend for that * language should handle it. */ if (cogl_pipeline_get_user_program (pipeline)) return FALSE; /* The fixed progend can't handle the per-vertex point size * attribute */ if (cogl_pipeline_get_per_vertex_point_size (pipeline)) return FALSE; return TRUE; }
static CoglBool _cogl_pipeline_progend_fixed_arbfp_start (CoglPipeline *pipeline) { _COGL_GET_CONTEXT (ctx, FALSE); if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FIXED))) return FALSE; if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED)) return FALSE; /* Vertex snippets are only supported in the GLSL fragend */ if (_cogl_pipeline_has_vertex_snippets (pipeline)) return FALSE; /* Validate that we can handle the fragment state using ARBfp */ if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ARBFP)) return FALSE; /* Fragment snippets are only supported in the GLSL fragend */ if (_cogl_pipeline_has_fragment_snippets (pipeline)) return FALSE; /* The ARBfp progend can't handle the per-vertex point size * attribute */ if (cogl_pipeline_get_per_vertex_point_size (pipeline)) return FALSE; return TRUE; }
static CoglBool _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline, unsigned long pipelines_difference) { CoglPipelineShaderState *shader_state; _COGL_GET_CONTEXT (ctx, FALSE); shader_state = get_shader_state (pipeline); if (shader_state->source) { const char *source_strings[2]; GLint lengths[2]; GLint compile_status; GLuint shader; CoglPipelineSnippetData snippet_data; CoglPipelineSnippetList *vertex_snippets; COGL_STATIC_COUNTER (vertend_glsl_compile_counter, "glsl vertex compile counter", "Increments each time a new GLSL " "vertex shader is compiled", 0 /* no application private data */); COGL_COUNTER_INC (_cogl_uprof_context, vertend_glsl_compile_counter); g_string_append (shader_state->header, "void\n" "cogl_real_vertex_transform ()\n" "{\n" " cogl_position_out = " "cogl_modelview_projection_matrix * " "cogl_position_in;\n" "}\n"); g_string_append (shader_state->source, " cogl_vertex_transform ();\n" " cogl_color_out = cogl_color_in;\n" "}\n"); vertex_snippets = get_vertex_snippets (pipeline); /* Add hooks for the vertex transform part */ memset (&snippet_data, 0, sizeof (snippet_data)); snippet_data.snippets = vertex_snippets; snippet_data.hook = COGL_SNIPPET_HOOK_VERTEX_TRANSFORM; snippet_data.chain_function = "cogl_real_vertex_transform"; snippet_data.final_name = "cogl_vertex_transform"; snippet_data.function_prefix = "cogl_vertex_transform"; snippet_data.source_buf = shader_state->header; _cogl_pipeline_snippet_generate_code (&snippet_data); /* Add all of the hooks for vertex processing */ memset (&snippet_data, 0, sizeof (snippet_data)); snippet_data.snippets = vertex_snippets; snippet_data.hook = COGL_SNIPPET_HOOK_VERTEX; snippet_data.chain_function = "cogl_generated_source"; snippet_data.final_name = "cogl_vertex_hook"; snippet_data.function_prefix = "cogl_vertex_hook"; snippet_data.source_buf = shader_state->source; _cogl_pipeline_snippet_generate_code (&snippet_data); g_string_append (shader_state->source, "void\n" "main ()\n" "{\n" " cogl_vertex_hook ();\n"); /* If there are any snippets then we can't rely on the projection matrix to flip the rendering for offscreen buffers so we'll need to flip it using an extra statement and a uniform */ if (_cogl_pipeline_has_vertex_snippets (pipeline)) { g_string_append (shader_state->header, "uniform vec4 _cogl_flip_vector;\n"); g_string_append (shader_state->source, " cogl_position_out *= _cogl_flip_vector;\n"); } g_string_append (shader_state->source, "}\n"); GE_RET( shader, ctx, glCreateShader (GL_VERTEX_SHADER) ); lengths[0] = shader_state->header->len; source_strings[0] = shader_state->header->str; lengths[1] = shader_state->source->len; source_strings[1] = shader_state->source->str; _cogl_glsl_shader_set_source_with_boilerplate (ctx, NULL, shader, GL_VERTEX_SHADER, 2, /* count */ source_strings, lengths); GE( ctx, glCompileShader (shader) ); GE( ctx, glGetShaderiv (shader, GL_COMPILE_STATUS, &compile_status) ); if (!compile_status) { GLint len = 0; char *shader_log; GE( ctx, glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &len) ); shader_log = g_alloca (len); GE( ctx, glGetShaderInfoLog (shader, len, &len, shader_log) ); g_warning ("Shader compilation failed:\n%s", shader_log); } shader_state->header = NULL; shader_state->source = NULL; shader_state->gl_shader = shader; } if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM) && (pipelines_difference & COGL_PIPELINE_STATE_POINT_SIZE)) { CoglPipeline *authority = _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_POINT_SIZE); GE( ctx, glPointSize (authority->big_state->point_size) ); } return TRUE; }