1

Introduction

I am attempting to create an OpenGL shader in D using Derelict's OpenGL binding. During the making of a quick test application to see if I could put everything together, it worked just fine, but when I started organizing things slightly better I have run into a highly odd (in terms of my understanding of the D language and the bindings) errror. Hopefully, I am simply being foolish.

If I were to call glCreateShader(GL_VERTEX_SHADER) in the module spacegame.game.game:

module spacegame.game.game;

import lib.window.stage;

import derelict.opengl;
import derelict.opengl.types;

mixin glFreeFuncs!(GLVersion.gl45);

/**
 * The game stage.
 */
class Game : Stage
{
    this ()
    {
        super();

        glCreateShader(GL_VERTEX_SHADER);
    }
}

It works just fine! There are no errors at all. On the other hand, if I were to import module lib.render.shaderprogram from the module above:

module lib.render.shaderprogram;

import std.stdio;

import derelict.opengl;
import derelict.opengl.types;

mixin glFreeFuncs!(GLVersion.gl45);

void makeShader ()
{
    glCreateShader(GL_VERTEX_SHADER);

    writeln("I never output!");
}

And call the makeShader function from the constructor where I called glCreateShader before (whereas it worked), I get the following error:

object.Error@(0): Access Violation

As far as I am aware, everything is the same, including the imports, right? As the shaderprogram module is only imported from the game module, the GL context will already have been set up, as in the first example.

What I cannot seem to understand is why the first example would work, whilst the second does not.

Is there some D language compiler magic I am not aware of here? Any pointers in the right direction would be highly appreciated.

Moreover

In the "quick test application" I mentioned before, I had no problem whatsoever rendering a simple triangle to a GLFW window. And rendering does work if I create the shader program inside the Game class described in the first example.

For separation, however, it would definitely be better if shader program creation could be separated out. ;-)

Edit: @RichardAndrewCattermole suggested I would verify that the pointer to glCreateShader is not null in the second example. It is. That would explain why the error occurs. As to why it is indeed null surprises me, considering the imports are the same in both cases (including the mixin).

D. Ataro
  • 1,711
  • 17
  • 38
  • Can you please verify that the pointer is non-null? – Richard Andrew Cattermole Mar 30 '18 at 13:37
  • @RichardAndrewCattermole Huh. In the `shaderprogram` module the pointer to `glCreateShader` is in fact `null`. But with the imports being the same in the second module, and it being imported from the first, surely the pointer should have the same value as in the first case, right? – D. Ataro Mar 30 '18 at 13:42
  • How many ``mixin glFreeFuncs``'s do you have after the move? My guess is its being funky when it is > 1. – Richard Andrew Cattermole Mar 30 '18 at 13:48
  • @RichardAndrewCattermole I have four at the moment, scattered around in my project, all mixing in the same thing. Unfortunately I am not all to familiar with mixins. But it did work well having three scattered around. Would a viable option, should this prove to be the problem, be to have the `mixin` occur inside another module that I then import into the files that need it? – D. Ataro Mar 30 '18 at 13:53
  • 1
    Yes do that. Otherwise you're just wasting memory having X copies of the same thing around (that have to be loaded individually too!). – Richard Andrew Cattermole Mar 30 '18 at 14:25
  • @RichardAndrewCattermole This, in fact, made it work brilliantly. Looking back at the documentation for Derelict.GL3, they did actually recommend this behavior, which I missed completely and utterly. I would suggest you write an answer to the question so I can accept it as the correct one. Surely somebody has to be as unknowing as myself when it comes to D mixins. ;-) – D. Ataro Mar 30 '18 at 14:55
  • Should probably wrap it up in an answer and accept it. That will make it easier for people who come across the same issue in the future. – Bauss Mar 31 '18 at 23:44

1 Answers1

0

As @RichardAndrewCattermole pointed out, I was creating X copies of the same thing in multiple places, which beyond reasonable doubt confused the Derelict GL3 package. And actually, according to the official documentation of Derelict, it does state that you should wrap the implementation using glFreeFuncs into its own file, so that you can require that whenever necessary.

Doing so eliminated the null pointer.

This means that whenever the need to use the library arises, a simple import gl; like so is all that's required.

D. Ataro
  • 1,711
  • 17
  • 38