1 module ws.gl.batch; 2 3 import ws.gl.gl, ws.exception, ws.io; 4 5 __gshared: 6 7 8 class Batch { 9 10 alias float[2] tex; 11 alias float[3] vec; 12 alias float[4] color; 13 14 void begin(int verts, uint type = GL_TRIANGLES){ 15 assert(gl.active()); 16 verticeCount = verts; 17 currentVert = 0; 18 this.type = type; 19 glGenVertexArrays(1, cast(uint*)&vao); 20 glBindVertexArray(vao); 21 } 22 23 void finish(){ 24 assert(!done); 25 foreach(array; arrays){ 26 glBindBuffer(GL_ARRAY_BUFFER, array.globj); 27 glUnmapBuffer(GL_ARRAY_BUFFER); 28 } 29 30 glBindVertexArray(vao); 31 32 foreach(array; arrays){ 33 glBindBuffer(GL_ARRAY_BUFFER, array.globj); 34 glEnableVertexAttribArray(array.attributeId), 35 glVertexAttribPointer(array.attributeId, array.size, GL_FLOAT, GL_FALSE, 0, null); 36 } 37 38 done = true; 39 glBindVertexArray(0); 40 } 41 42 void draw(){ 43 if(!done) 44 return; 45 glBindVertexArray(vao); 46 glDrawArrays(type, 0, verticeCount); 47 //glBindVertexArray(0); 48 } 49 50 void add(vec pos){ 51 addVertex(pos); 52 currentVert++; 53 } 54 55 void addPoint(vec pos, color col){ 56 addVertex(pos); 57 addColor(col); 58 currentVert++; 59 } 60 61 void addPoint(vec pos, vec normal){ 62 addVertex(pos); 63 addNormal(normal); 64 currentVert++; 65 } 66 67 void addPoint(vec pos, vec normal, color col){ 68 addVertex(pos); 69 addNormal(normal); 70 addColor(col); 71 currentVert++; 72 } 73 74 void addPoint(vec pos, tex t){ 75 addVertex(pos); 76 addTex(t); 77 currentVert++; 78 } 79 80 void addPoint(vec pos, vec normal, tex t){ 81 addVertex(pos); 82 addNormal(normal); 83 addTex(t); 84 currentVert++; 85 } 86 87 /*~this(){ 88 glDeleteVertexArrays(1, &vao); 89 }*/ 90 91 void updateVertices(float[] data, size_t pos = 0, size_t length = 1){ 92 glBindBuffer(GL_ARRAY_BUFFER, vertices.globj); 93 glBufferSubData(GL_ARRAY_BUFFER, pos*3*float.sizeof, length*3*float.sizeof, data.ptr); 94 } 95 96 protected: 97 98 uint vao; 99 uint type; 100 101 bool done = false; 102 int verticeCount = 0; 103 int currentVert = 0; 104 105 class Array { 106 this(int size, uint attributeId){ 107 assert(!done); 108 assert(vao); 109 this.size = size; 110 this.attributeId = attributeId; 111 glGenBuffers(1, cast(uint*)&globj); 112 glBindBuffer(GL_ARRAY_BUFFER, globj); 113 glBufferData(GL_ARRAY_BUFFER, float.sizeof*size*verticeCount, null, GL_DYNAMIC_DRAW); 114 glBindBuffer(GL_ARRAY_BUFFER, globj); 115 array = cast(float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); 116 arrays ~= this; 117 //gl.check(); 118 if(!array) 119 exception("Failed to create array buffer"); 120 } 121 float* array = null; 122 uint globj = 0; 123 uint size; 124 uint attributeId; 125 /*~this(){ 126 glDeleteBuffers(1, &globj); 127 }*/ 128 } 129 130 Array vertices; 131 Array normals; 132 Array colors; 133 Array texCoords; 134 Array[] arrays; 135 136 void addVertex(vec v){ 137 if(!vertices) 138 vertices = new Array(3, gl.attributeVertex); 139 float* o = vertices.array+currentVert*3; 140 /+ 141 o[0] = v[0]; 142 o[1] = v[1]; 143 o[2] = v[2]; 144 +/ 145 o[0..3] = v[0..3]; 146 } 147 148 void addNormal(vec v){ 149 if(!normals) 150 normals = new Array(3, gl.attributeNormal); 151 float* o = normals.array+currentVert*3; 152 /+ 153 o[0] = v[0]; 154 o[1] = v[1]; 155 o[2] = v[2]; 156 +/ 157 o[0..3] = v[0..3]; 158 } 159 160 void addColor(color c){ 161 if(!colors) 162 colors = new Array(4, gl.attributeColor); 163 float* o = colors.array+currentVert*4; 164 o[0] = c[0]; 165 o[1] = c[1]; 166 o[2] = c[2]; 167 o[3] = c[3]; 168 } 169 170 void addTex(tex t){ 171 if(!texCoords) 172 texCoords = new Array(2, gl.attributeTexture); 173 texCoords.array[currentVert*2] = t[0]; 174 texCoords.array[currentVert*2+1] = t[1]; 175 } 176 177 }