mercredi 28 décembre 2016

How to associate data to the elements in a collection without modifying the elements?

usually, when I'm doing OpenGL programming, I have a Mesh class like this:

public class Mesh {

    // General 3D stuff
    List<Vector3f> vertices = new ArrayList<>();
    List<Vector3f> normals = new ArrayList<>();
    List<Vector2f> texCoords = new ArrayList<>();

    // OpenGL-specific stuff
    protected int vertices;
    protected boolean dirty;
    protected int vertexArrayID = -1;
    protected int vertexBufferID = -1;

    ...

}

However, the application I'm working on right now is much more general, and I'd like to keep the OpenGL-specific stuff separate from the OpenGL stuff. For example, someone might want to store the Mesh as an STL file and have it 3D-printed, or send it off to a Raytrace renderer to make it look nice. In that case, the OpenGL-specific data is useless.

In other words, this implementation of the Mesh class violates the single responsibility principle.

Now, one solution I can think of is the following:

public class Mesh {

    // General 3D stuff
    List<Vector3f> vertices = new ArrayList<>();
    List<Vector3f> normals = new ArrayList<>();
    List<Vector2f> texCoords = new ArrayList<>();
}

public class GlMesh extends Mesh implements GlDrawable {

    // OpenGL-specific stuff
    protected int vertices;
    protected boolean dirty;
    protected int vertexArrayID = -1;
    protected int vertexBufferID = -1;
}

However, now there are still OpenGL-specific objects in the datastructure that is output from the algorithm that generates it. The Mesh generator needs to know it should create a GlMesh rather than a Mesh, and thus knows about the OpenGL rendering module, something I'd really rather avoid.

Now, we can do something like this:

public class Mesh {

    // General 3D stuff
    List<Vector3f> vertices = new ArrayList<>();
    List<Vector3f> normals = new ArrayList<>();
    List<Vector2f> texCoords = new ArrayList<>();
}

public class GlMesh {

    // OpenGL-specific stuff
    protected int vertices;
    protected boolean dirty;
    protected int vertexArrayID = -1;
    protected int vertexBufferID = -1;
}

Map<Mesh, GlMesh> meshToGlMesh = (whatever)

However, now the rendering system has to do extensive bookkeeping to map the Mesh to the corresponding GlMesh, which is just asking for trouble.

Is there a good way to solve this that I'm missing?

Aucun commentaire:

Enregistrer un commentaire