1. Jason McKesson
  2. glLoadGen
  3. Issues
Issue #35 open

Rust module

Brendan Zabarauskas
created an issue

I just to alert you, I am in the process of implementing a Rust module for glLoadGen. Due to the language's focus on concurrency and safety Rust does not have global state, so I'm storing the function pointers in a struct, with fields corresponding to each function pointer.

Here's a snippet of how it currently looks:

use core::cast::transmute;
use core::libc::*;

...

pub struct GL {
    CullFace: extern "C" fn(mode: GLenum),
    FrontFace: extern "C" fn(mode: GLenum),
    Hint: extern "C" fn(target: GLenum, mode: GLenum),
    LineWidth: extern "C" fn(width: GLfloat),
    PointSize: extern "C" fn(size: GLfloat),
    PolygonMode: extern "C" fn(face: GLenum, mode: GLenum),

    ...
}

macro_rules! get_funptr(
    ($loadfn:id -> $symbol:expr) => (
        unsafe { transmute(
            & $loadfn (transmute(&( $symbol [0]))
        ) }
    )
)

pub impl GL {
    /**
     * Load each OpenGL symbol using a custom load function. This allows for the
     * use of functions like `glfwGetProcAddress` or `SDL_GL_GetProcAddress`.
     *
     * ~~~
     * let gl = gl::load_with(glfw::get_proc_address);
     * ~~~
     */
    static fn load_with(loadfn: &fn(symbol: *c_char) -> *c_void) -> GL {
        GL {
            CullFace: get_funptr!(loadfn -> "glCullFace"),
            FrontFace: get_funptr!(loadfn -> "glFrontFace"),
            Hint: get_funptr!(loadfn -> "glHint"),
            LineWidth: get_funptr!(loadfn -> "glLineWidth"),
            PointSize: get_funptr!(loadfn -> "glPointSize"),
            PolygonMode: get_funptr!(loadfn -> "glPolygonMode"),

            ...
        }
    }

    #[inline(always)] fn CullFace(&self, mode: GLenum) { (self.CullFace)(mode); }
    #[inline(always)] fn FrontFace(&self, mode: GLenum) { (self.FrontFace)(mode); }
    #[inline(always)] fn Hint(&self, target: GLenum, mode: GLenum) { (self.FrontFace)(mode); }
    #[inline(always)] fn LineWidth(&self, width: GLfloat) { (self.LineWidth)(width) }
    #[inline(always)] fn PointSize(&self, size: GLfloat) { (self.PointSize)(size) }
    #[inline(always)] fn PolygonMode(&self, face: GLenum, mode: GLenum) { (self.PolygonMode)(face, mode) }

    ...
}

Here's an extended example generated from the 3.3 core profile.

Just note, this code currently does not compile with the latest Rust compiler – I am awaiting updates to the foreign-function interface to allow us to call external function pointers. The module is also unfinished, and does not generate GLX and WGL correctly.

I'm not sure if this is something that you'd be interested in merging into the main repository, but I thought I'd let you know what I'm up to anyway. I'm currently maintaining my fork on Github, using git-hg as a bridge, so pushing to your Mercurial repository shouldn't be a problem.

If you would like to chat about this in real time, I'm usually available on irc.mozilla.org #rust.

Comments (7)

  1. Jason McKesson repo owner

    Thanks for the head's up. Once you have it working reasonably well (hopefully with some kind of tests), I'd be happy to incorporate it into the main line. As long as you keep up with it's maintenance, of course.

  2. Jason McKesson repo owner

    I mean a test. Like the projects in the tests directory. They make sure that the various styles actually work to some degree. Obviously my test system is built around C/C++, but there should be some system you can add that will allow you to easily make and compile a Rust application that uses your style, to ensure that it works.

  3. Log in to comment