1 module des.gl.simple.meshobj;
2 
3 import des.math.linear;
4 import des.util.logsys;
5 import des.gl.simple.object;
6 import des.util.stdext.algorithm;
7 
8 ///
9 class MeshData
10 {
11     ///
12     string name;
13     ///
14     vec3[] vertices;
15     ///
16     vec3[] normals, tangents, bitangents;
17     ///
18     vec4[][] colors;
19     ///
20     vec3[][] texcrds;
21     ///
22     uint[] texcrdsdims;
23     ///
24     uint[] indices;
25 }
26 
27 ///
28 class GLMeshObject : GLSimpleObject
29 {
30 protected:
31 
32     ///
33     MeshData mesh_data;
34 
35     ///
36     GLBuffer vertices;
37     ///
38     GLBuffer normals, tangents, bitangents;
39     ///
40     GLBuffer[] colors;
41     ///
42     GLBuffer[] texcrds;
43     ///
44     GLBuffer indices;
45 
46     ///
47     abstract void prepareAttribPointers();
48 
49 public:
50 
51     ///
52     this( string shader_source, MeshData md )
53     in{ assert( md !is null ); } body
54     {
55         super( shader_source );
56         mesh_data = md;
57         prepareBuffers();
58         prepareAttribPointers();
59     }
60 
61     ///
62     this( CommonGLShaderProgram sh, MeshData md )
63     in
64     {
65         assert( sh !is null );
66         assert( md !is null );
67     }
68     body
69     {
70         super( sh );
71         mesh_data = md;
72         prepareBuffers();
73         prepareAttribPointers();
74     }
75 
76 protected:
77 
78     ///
79     void prepareBuffers()
80     {
81         logger.info( "work with mesh '%s'", mesh_data.name );
82 
83         vertices = createArrayBuffer();
84         vertices.setData( mesh_data.vertices );
85 
86         logger.trace( "vertices: ", mesh_data.vertices.length );
87 
88         if( mesh_data.normals.length )
89         {
90             normals = newEMM!GLBuffer();
91             normals.setData( mesh_data.normals );
92             logger.trace( "with normals" );
93         }
94 
95         if( mesh_data.tangents.length )
96         {
97             tangents = newEMM!GLBuffer();
98             tangents.setData( mesh_data.tangents );
99             logger.trace( "with tangents" );
100         }
101 
102         if( mesh_data.bitangents.length )
103         {
104             bitangents = newEMM!GLBuffer();
105             bitangents.setData( mesh_data.bitangents );
106             logger.trace( "with bitangents" );
107         }
108 
109         foreach( i; 0 .. mesh_data.colors.length )
110         {
111             auto cbuf = newEMM!GLBuffer();
112             cbuf.setData( mesh_data.colors[i] );
113             colors ~= cbuf;
114             logger.trace( "with colors %d", i );
115         }
116 
117         foreach( i; 0 .. mesh_data.texcrds.length )
118         {
119             auto tbuf = newEMM!GLBuffer();
120             switch( mesh_data.texcrdsdims[i] )
121             {
122                 case 1:
123                     tbuf.setData( amap!(a=>a.x)( mesh_data.texcrds[i] ) );
124                     break;
125                 case 2:
126                     tbuf.setData( amap!(a=>a.xy)( mesh_data.texcrds[i] ) );
127                     break;
128                 case 3:
129                     tbuf.setData( mesh_data.texcrds[i] );
130                     break;
131                 default:
132                     throw new Exception( "WTF?: texture coordinate dims == " ~ 
133                             to!string( mesh_data.texcrdsdims[i] ) );
134             }
135             texcrds ~= tbuf;
136             logger.trace( "with texcrds %d (%dD)", i, mesh_data.texcrdsdims[i] );
137         }
138 
139         if( mesh_data.indices.length )
140         {
141             indices = createIndexBuffer();
142             indices.setData( mesh_data.indices );
143 
144             logger.trace( "with indices" );
145         }
146     }
147 }