Blog

Blog

Mewer

Posted at 01:43 on 21 Feb 2013

If you sometimes find yourself confused about whether you should use the word ‘fewer’ or ‘less’, here is a handy table to help you:

image

It is extremely important to pick the right word. For example if you think there are too many pedantic people in your office you should say ‘my office has the manyest pedantic people’. If you were to incorrectly say ‘my office has the most pedantic people’, your listener would immediately assume you meant that the people in your office are more pedantic than any other people. This could cause untold confusion and misunderstanding. It is therefore essential that if you hear a friend incorrectly say ‘more’ when they mean ‘manyer’ you must immediately interrupt and correct them.

Rig 1

Posted at 18:39 on 31 Oct 2012

Today is the first release of Rig. This is a project that Robert Bragg and I have been working for the past few months. I won't try to describe it here, but instead I will try to entice you with a screenshot and ask you to take a look at Robert's detailed blog post.

image

Cogl Shader Snippets

Posted at 22:37 on 07 Dec 2011

Cogl has been getting some love lately to move towards the 2.0 API that will eventually replace the existing API. Now that Cogl has split out from Clutter and it can be used as a standalone library we are getting close to the goal of Cogl being a convenient replacement for OpenGL. However one thing that until recently has been severely lacking for Cogl to be a credible modern graphics library is good support for shaders. Cogl has had a sort of shader support for a long time but it has hardly been touched since the days when Cogl was just a very thin wrapper over the GL API. Cogl has evolved a lot since then so the previous shader support no longer fits with Cogl's design.

We've finally got around to improving this situation so there are now a few changes in git master of Cogl to make this better. In 2.0 land, instead of having to create a CoglProgram to replace the entire of either the vertex or fragment pipeline you can now create CoglSnippets. These can be inserted at specific hook points on a CoglPipeline to either wrap around or completely replace a part of the pipeline. For example, imagine we have a function in GLSL that can take an input colour and convert it to black-and-white. If we wanted to use this in Cogl we would previously have had to implement the entire fragment pipeline. Usually this would mean having to create a sampler uniform, update that uniform and writing the code to get a texel from the sampler. If we wanted to use this shader in another situation without texturing, for example when drawing a solid colour rectangle, we would have to write another shader that includes the function without the texturing.

With the snippets API we can now create an object that just contains the black-and-white conversion in a single line, like this:

snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
                            NULL,
                            "cogl_color_out.rgb = "
                            "vec3 (length (cogl_color_out.rgb) / 1.732);");

Then we can attach that snippet to any CoglPipeline and Cogl will fill in the rest of the code needed to make it work. It can be attached to multiple pipelines, for example one with texturing and one without.

The second feature that has landed recently is to be able to store uniform values on a CoglPipeline. The idea behind the design of Cogl is that you will store as much of the GL state as possible in a CoglPipeline object and try to switch between these cached states rather than redescribing the state to the graphics library every time something is drawn. That way Cogl can minimise the state changes by recognising the minimal set of differences between two pipelines. The previous approach for uniforms - which was the same as OpenGL where the uniform values are attached to the program object - doesn't match well to this design. If you wanted to use a program multiple times with different values then you would have to reset the values on the program for every primitive.

In Cogl master you can instead encapsulate these uniform values on the pipeline and Cogl can efficiently recognise which uniforms are different between two pipelines sharing the same program and avoid flushing uniforms that haven't changed. For example, imagine this snippet which just replaces the red component of the fragment colour based on the value of a uniform:

snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
                            "uniform float red_value;",
                            "cogl_color_out.r = red_value;");
pipeline = cogl_pipeline_new ();
cogl_pipeline_add_snippet (pipeline, snippet);
cogl_object_unref (snippet);

Now if we want to frequently paint using this snippet with two different values, we can create two pipelines like this:

pipeline1 = cogl_pipeline_copy (pipeline);
location = cogl_pipeline_get_uniform_location (pipeline, "red_value");
cogl_pipeline_set_uniform_1f (pipeline1, location, 0.5f);

pipeline2 = cogl_pipeline_copy (pipeline);
location = cogl_pipeline_get_uniform_location (pipeline, "red_value");
cogl_pipeline_set_uniform_1f (pipeline2, location, 0.8f);

Now we can draw with these two pipelines easily:

cogl_push_source (pipeline1);
cogl_rectangle (0, 0, 10, 10);
cogl_pop_source ();

cogl_push_source (pipeline2);
cogl_rectangle (10, 10, 20, 20);
cogl_pop_source ();

Cogl will quickly know that the two pipelines are using the same program because they are copied from the same parent so it will only flush the state for the new uniform value when switching between the two.

The third recent addition to Cogl related to shaders is support for custom attributes. The API has already been in place for this for a while from both CoglPrimitive and the now deprecated CoglVertexBuffer. However it was never actually connected together properly so no-one could use it. The custom attributes can be set by just naming them when a CoglAttribute is created. Here is a short example:

/* Create a pipeline with a snippet using a custom attribute. This
   will just replace the red component of the colour using a float */
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
                            "attribute float redness;",
                            "cogl_color_out.r = redness;");
pipeline = cogl_pipeline_new ();
cogl_pipeline_add_snippet (pipeline, snippet);
cogl_object_unref (snippet);

/* Create a primitive with two attributes. One will be our custom
   attribute and the other will be the normal position attribute */
static const float verts[] = { 0, 0, 0.0,
                               100, 0, 0.5,
                               50, 100, 1.0 };
CoglAttributeBuffer *buffer =
 cogl_attribute_buffer_new (sizeof (verts), verts);
CoglAttribute *attributes[2];
attributes[0] = cogl_attribute_new (buffer,
                                    "cogl_position_in",
                                    /* Stride */
                                    sizeof (float) * 3,
                                    /* Offset */
                                    0,
                                    /* n_components */
                                    2,
                                    COGL_ATTRIBUTE_TYPE_FLOAT);
attributes[1] = cogl_attribute_new (buffer,
                                    "redness",
                                    /* Stride */
                                    sizeof (float) * 3,
                                    /* Offset */
                                    sizeof (float) * 2,
                                    /* n_components */
                                    1,
                                    COGL_ATTRIBUTE_TYPE_FLOAT);
primitive =
  cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                      3, /* n_vertices */
                                      attributes,
                                      2 /* n_attributes */);
cogl_object_unref (attributes[0]);
cogl_object_unref (attributes[1]);
cogl_object_unref (buffer);

/* Now we can draw with this primitive and pipeline */
cogl_push_source (pipeline);
cogl_primitive_draw (primitive);
cogl_pop_source ();

I've uploaded the current documentation to a temporary location if you want further details of the API. It's all still experimental so we'd very much welcome any testing and feedback. The Cogl developers can be contacted on the new mailing list or at #clutter on GIMPnet.

gtk-im-extra

Posted at 01:13 on 17 Nov 2011

Is anybody else using gtk-im-extra? If so you might be interested to know I've made a git repo (it's currently still in CVS!) and added some patches to make it build with GTK+3. It would be really great if someone would get this into a Fedora package so I don't have to keep building it.

 git clone git://git.busydoingnothing.co.uk/gtk-im-extra

Esperantaj domajnnomoj

Posted at 14:25 on 29 Sep 2011

Antaŭ ne longe mi tre volis registri domajnnomon kiu havas esperantajn literojn. Mi ne scias kial sed mi simple volis. Tio eblas pro IDN (internacigitaj domajnnomojn). Ekzemple, per tio ekzistas la domajnnomon http://müller.info/.

Tamen estas problemo pri sekureco kun IDN. Ekzemple, oni povus registri la adreson http://pаypаl.com/. La literoj ‘а’ en tiu ligilo ne estas same kiel la latina litero ‘a’ kiun oni kutime uzas en esperanto sed ĝi estas la rusa litero. Do ĝi estas tute alia retejo ol la oficiala paypal.com sed ĝi aspektas same. La retumiloj evitas tiun problemon per montri la adreson per alia aspekto kiu tute ne estas konfuzebla. Ekzemple, en Firefox tiu ligilo aspektas kiel “http://xn--pypl-53dc.com/” en la adresbreto.

Firefox inkluzivas liston de supraj retregionoj al kiuj ĝi permesos montri la internaciajn literojn. Ĝi ne inkluzivas adresojn ĉe .com ĉar la organizo kiu estras tiun retregionon permesas ion ajn adreson do ĝi estas tre malsekura. Aliaj organizoj permesas nur la literojn de kelkaj lingvoj kaj malpermesas nomojn kiuj evidente estas trompaj. La listo de nomoj kun tia bona organizo nun en Firefox estas: .ac, .ar, .asia, .at, .biz, .br, .cat, .ch, .cl, .cn, .de, .dk, .es, .fi, .gr, .hu, .il, .info, .io, .ir, .is, .jp, .kr, .li, .lt, .lu, .lv, .museum, .no, .nz, .org, .pl, .pr, .se, .sh, .tel, .th, .tm, .tw, .ua kaj .vn. La plejmulto el ili estas uzata por iu specifa lando kaj la organizo nur akceptas la lingvon de tiu lando. Kaj ofte tiaj organizoj eĉ ne permesas registrojn de homoj kiuj ne loĝas en tiuj landoj.

Interesa escepto estas .io. Tiu nomo apartenas al la Brita Hindoceana Teritorio sed ĝi permesas registrojn de iu ajn. Plej interesa estas ke ili specife permesas esperantajn literojn! Ekzemple estus amuze registri http://suŝ.io/.

Verŝajne la plej utila por esperantio el tiuj retregiono estus .org. Tamen la organizo por tio ne permesas esperantajn literojn. La nuraj lingvoj kiujn ili akceptas estas la dana, germana, hungara, islanda, korea, latvia, litovia, pola, hispana, sveda kaj ĉina. Do mia peto al la esperanta komuno estas ke ni kune petu al .org ke ili permesu esperantajn literojn. Eble iu esperanta organizo kiel UEA aŭ E@I povos fari oficialan leteron al ili? Ĉu iu havas proponon por helpi tion?