Search code examples
openglsdlvala

Vala OpenGL glGenTexture


colors = surface->format->BytesPerPixel;
if (colors == 4) {   // alpha
    if (surface->format->Rmask == 0x000000ff)
        texture_format = GL_RGBA;
    else
        texture_format = GL_BGRA;
} else {             // no alpha
    if (surface->format->Rmask == 0x000000ff)
        format = GL_RGB;
    else
        format = GL_BGR;
}

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture); 
glTexImage2D(GL_TEXTURE_2D, 0, colors, surface->w, surface->h, 0,
                    texture_format, GL_UNSIGNED_BYTE, surface->pixels);

I am trying to convert that code I found on Stack Overflow to Vala. However, I'm having trouble with glGenTextures.

The first part was straightforward:

    int texture_format;
    uchar colors = screen.format.BytesPerPixel;
    if (colors == 4) {
        if (screen.format.Rmask == 0x000000ff) {
            texture_format = GL_RGBA;
        } else {
            texture_format = GL_BGRA;
        }
    } else {
        if (screen.format.Rmask == 0x000000ff) {
            texture_format = GL_RGB;
        } else {
            texture_format = GL_BGR;
        }
    }

This, part, though, I don't know how to convert: glGenTextures(1, &texture);

I tried:

    GL.GLuint[] texture = {};
    glGenTextures (1, texture);

I got:

.vala:46.27-46.33: error: Argument 2: Cannot pass value to reference or output parameter

I also tried:

GL.GLuint[] texture = {};
glGenTextures (1, out texture);

I got:

ERROR:valaccodearraymodule.c:1183:vala_ccode_array_module_real_get_array_length_cvalue: assertion failed: (_tmp48_)

I tried:

glGenTextures (1, &texture);

I got:

.vala:46.27-46.34: error: Argument 2: Cannot pass value to reference or output parameter

I tried various other similar things, any ideas?


Solution

  • Sounds like the binding is wrong. Based on the glGenTextures man page, the Vala binding should be something like:

    public static void glGenTextures ([CCode (array_length_pos = 0.9)] GL.GLuint[] textures);
    

    The proper way to call it would be something like:

    GL.GLuint[] textures = new GL.GLuint[1];
    glGenTextures (textures);
    // your texture is textures[0]
    

    Of course that's not very nice for the use case you're looking at where you just want a single textures, but it's not that big of a deal. The problem is that you have to allocate an array on the heap... I don't doubt this is a performance-sensitive area of code, so I probably wouldn't bother, but you could always create an alternate version:

    [CCode (cname = "glGenTextures")]
    public static void glGenTexture (GL.GLsizei n, out GL.GLuint texture);
    

    Which you could then call with

    GL.GLuint texture;
    glGenTexture (1, out texture);
    

    In spite of the fact that you can only use this version to generate a single texture you still have to pass the first argument manually.