1 /** 2 * このモジュールをユーザーが直接使用することはありません。 3 */ 4 5 module grape.buffer; 6 7 import derelict.opengl3.gl3; 8 import derelict.sdl2.sdl; 9 import derelict.sdl2.image; 10 11 import std.stdio; 12 import std.math; 13 import std.conv; 14 15 import grape.window; 16 import grape.file; 17 import grape.math; 18 import grape.camera; 19 import grape.surface; 20 import grape.shader; 21 22 enum DrawMode { 23 Points = GL_POINTS, 24 Lines = GL_LINES, 25 LineLoop = GL_LINE_LOOP, 26 LineStrip = GL_LINE_STRIP, 27 Triangles = GL_TRIANGLES, 28 TriangleStrip = GL_TRIANGLE_STRIP, 29 TriangleFan = GL_TRIANGLE_FAN, 30 //Quads = GL_QUADS 31 } 32 33 class UniformN { 34 public: 35 static this() { 36 _uniInt["1i"] = (location, value) { glUniform1i(location, value); }; 37 _uniIntV["1iv"] = (location, value, num) { glUniform1iv(location, num, value.ptr); }; 38 _uniIntV["2iv"] = (location, value, num) { glUniform2iv(location, num, value.ptr); }; 39 _uniFloat["1f"] = (location, value) { glUniform1f(location, value); }; 40 _uniFloatV["1fv"] = (location, value, num) { glUniform1fv(location, num, value.ptr); }; 41 _uniFloatV["2fv"] = (location, value, num) { glUniform2fv(location, num, value.ptr); }; 42 _uniFloatV["3fv"] = (location, value, num) { glUniform3fv(location, num, value.ptr); }; 43 _uniFloatV["4fv"] = (location, value, num) { glUniform4fv(location, num, value.ptr); }; 44 _uniFloatV["mat4fv"] = (location, value, num) { glUniformMatrix4fv(location, num, GL_FALSE, value.ptr); }; 45 } 46 47 static void locate(in string name, in int value, in string type, in int num, in GLint location) { 48 _uniInt[type](location, value); 49 } 50 51 static void locate(in string name, in int[] value, in string type, in int num, in GLint location) { 52 _uniIntV[type](location, value, num); 53 } 54 55 static void locate(in string name, in float value, in string type, in int num, in GLint location) { 56 _uniFloat[type](location, value); 57 } 58 59 static void locate(in string name, in float[] value, in string type, in int num, in GLint location) { 60 _uniFloatV[type](location, value, num); 61 } 62 63 private: 64 static void delegate(in GLint, in int)[string] _uniInt; 65 static void delegate(in GLint, in int[], in int)[string] _uniIntV; 66 static void delegate(in GLint, in float)[string] _uniFloat; 67 static void delegate(in GLint, in float[], in int)[string] _uniFloatV; 68 } 69 70 class UniformLocationN { 71 public: 72 static void attach(T)(in GLuint program, in string name, in T value, in string type, in int num=1) { 73 auto location = glGetUniformLocation(program, cast(char*)name); 74 _uniformN.locate(name, value, type, num, location); 75 } 76 77 private: 78 static UniformN _uniformN; 79 } 80 81 class AttributeLocationN { 82 public: 83 static void attach(in GLuint program, in string name, in int stride, in int i) { 84 glBindAttribLocation(program, i, cast(char*)name); 85 _location = glGetAttribLocation(program, cast(char*)name); 86 locate(stride); 87 } 88 89 private: 90 static void locate(in int stride) { 91 glEnableVertexAttribArray(_location); 92 glVertexAttribPointer(_location, stride, GL_FLOAT, GL_FALSE, 0, null); 93 } 94 95 static GLint _location; 96 } 97 98 class VBO { 99 public: 100 this() { 101 glGenBuffers(1, &_id); 102 } 103 104 ~this() { 105 glDeleteBuffers(1, &_id); 106 } 107 108 void set(T)(in GLuint program, in T data, in string name, in int stride, in int i) { 109 glBindBuffer(GL_ARRAY_BUFFER, _id); 110 glBufferData(GL_ARRAY_BUFFER, data[0].sizeof*data.length, data.ptr, GL_STREAM_DRAW); 111 AttributeLocationN.attach(program, name, stride, i); 112 glBindBuffer(GL_ARRAY_BUFFER, 0); 113 } 114 115 private: 116 GLuint _id; 117 } 118 119 class IBO { 120 public: 121 this() { 122 glGenBuffers(1, &_id); 123 } 124 125 ~this() { 126 glDeleteBuffers(1, &_id); 127 } 128 129 void create(in int[] index) { // const 130 _index = index.dup; 131 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _id); 132 glBufferData(GL_ELEMENT_ARRAY_BUFFER, _index[0].sizeof*_index.length, _index.ptr, GL_STREAM_DRAW); 133 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 134 } 135 136 void draw(in DrawMode mode) { 137 glDrawElements(mode, cast(int)_index.length, GL_UNSIGNED_INT, _index.ptr); 138 } 139 140 private: 141 GLuint _id; 142 int[] _index; 143 } 144 145 class RBO { 146 public: 147 this() { 148 glGenRenderbuffers(1, &_id); 149 } 150 151 ~this() { 152 glDeleteRenderbuffers(1, &_id); 153 } 154 155 void create(T)(in T type, in int w, in int h) { 156 glBindRenderbuffer(GL_RENDERBUFFER, _id); 157 glRenderbufferStorage(GL_RENDERBUFFER, type, w, h); 158 glBindRenderbuffer(GL_RENDERBUFFER, 0); 159 } 160 161 void attach(T)(in T type) { 162 glBindRenderbuffer(GL_RENDERBUFFER, _id); 163 glFramebufferRenderbuffer(GL_FRAMEBUFFER, type, GL_RENDERBUFFER, _id); 164 glBindRenderbuffer(GL_RENDERBUFFER, 0); 165 } 166 167 private: 168 GLuint _id; 169 } 170 171 class FBO { 172 public: 173 this() { 174 glGenFramebuffers(1, &_id); 175 } 176 177 ~this() { 178 glDeleteFramebuffers(1, &_id); 179 } 180 181 void create(T)(in T texture, GLenum attachment = GL_COLOR_ATTACHMENT0) { 182 glBindFramebuffer(GL_FRAMEBUFFER, _id); 183 glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture, 0); 184 glBindFramebuffer(GL_FRAMEBUFFER, 0); 185 } 186 187 void binded_scope(void delegate() dg) { 188 glBindFramebuffer(GL_FRAMEBUFFER, _id); 189 dg(); 190 glBindFramebuffer(GL_FRAMEBUFFER, 0); 191 } 192 193 // TODO Check whether fbo is certainly compiled 194 // glCheckFramebufferStatus 195 196 private: 197 GLuint _id; 198 } 199 200 class Texture { 201 public: 202 this() { 203 glGenTextures(1, &_id); 204 } 205 206 ~this() { 207 glDeleteTextures(1, &_id); 208 } 209 210 // TODO divide 211 void create(in int w, in int h, void* pixels, in int bytesPerPixel) { 212 set_draw_mode(bytesPerPixel); 213 _w = w; 214 _h = h; 215 216 glActiveTexture(GL_TEXTURE0); // TODO Cover other units 217 218 glBindTexture(GL_TEXTURE_2D, _id); 219 attach(w, h, pixels); filter(); 220 glBindTexture(GL_TEXTURE_2D, 0); 221 } 222 223 void create(Surface surf) { 224 create(surf.w, surf.h, surf.pixels, surf.bytes_per_pixel); 225 } 226 227 // Provides a scope that a texture is enabled. 228 void texture_scope(void delegate() dg) { 229 glBindTexture(GL_TEXTURE_2D, _id); 230 glActiveTexture(GL_TEXTURE0); 231 dg(); 232 glActiveTexture(GL_TEXTURE0); // Need? It's only needed if dg() changes the texture-unit. 233 glBindTexture(GL_TEXTURE_2D, 0); 234 } 235 236 alias _id this; // TODO private 237 238 @property { 239 int w() { 240 return _w; 241 } 242 243 int h() { 244 return _h; 245 } 246 } 247 248 private: 249 void set_draw_mode(in int bytesPerPixel) { 250 _mode = (bytesPerPixel == 4) ? GL_RGBA : GL_RGB; 251 } 252 253 void attach(in int w, in int h, void* pixels) { // const 254 glTexImage2D(GL_TEXTURE_2D, 0, _mode, w, h, 0, _mode, GL_UNSIGNED_BYTE, pixels); 255 } 256 257 void filter() { 258 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 259 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 260 } 261 262 GLuint _id; 263 int _mode; 264 int _w; 265 int _h; 266 } 267 268 269 /*******************ここから************************/ 270 deprecated class VBOHdr { 271 public: 272 this(in size_t num, in GLuint program) { 273 _num = num; 274 _vboList.length = _num; 275 for (int i; i<_num; ++i) 276 _vboList[i] = new OldVBO(program); 277 } 278 279 void create_vbo(in float[][] list...) { 280 assert(list.length == _num, "Doesn't match the number of vbo attributes"); 281 282 foreach(int i, data; list) 283 _vboList[i].create(data); 284 } 285 286 void enable_vbo(in string[] locNames, in int[] strides) { 287 assert(locNames.length == _num); 288 assert(strides.length == _num); 289 290 foreach (int i, vbo; _vboList) 291 vbo.attach(locNames[i], strides[i], i); 292 } 293 294 void draw(in DrawMode mode, in int num) { 295 glDrawArrays(mode, 0, num); 296 } 297 298 private: 299 size_t _num; 300 OldVBO[] _vboList; 301 } 302 303 deprecated class OldVBO { 304 public: 305 this(in GLuint program) { 306 _attLoc = new AttributeLocation(program); 307 glGenBuffers(1, &_id); 308 } 309 310 ~this() { 311 glDeleteBuffers(1, &_id); 312 } 313 314 void create(T)(in T data) { 315 glBindBuffer(GL_ARRAY_BUFFER, _id); 316 glBufferData(GL_ARRAY_BUFFER, data[0].sizeof*data.length, data.ptr, GL_STREAM_DRAW); 317 glBindBuffer(GL_ARRAY_BUFFER, 0); 318 } 319 320 void attach(in string name, in int stride, in int i) { 321 glBindBuffer(GL_ARRAY_BUFFER, _id); 322 _attLoc.attach(name, stride, i); 323 glBindBuffer(GL_ARRAY_BUFFER, 0); 324 } 325 326 private: 327 GLuint _id; 328 AttributeLocation _attLoc; 329 } 330 331 deprecated class AttributeLocation { 332 public: 333 this(in GLuint program) { 334 _program = program; 335 } 336 337 void attach(in string name, in int stride, in int i) { 338 glBindAttribLocation(_program, i, cast(char*)name); 339 _location = glGetAttribLocation(_program, cast(char*)name); 340 locate(stride); 341 } 342 343 private: 344 void locate(in int stride) { 345 glEnableVertexAttribArray(_location); 346 glVertexAttribPointer(_location, stride, GL_FLOAT, GL_FALSE, 0, null); 347 } 348 349 GLuint _program; 350 GLint _location; 351 } 352 353 deprecated class Uniform { 354 public: 355 this(){ 356 init(); 357 } 358 359 this(string vShader, string fShader) { 360 this(); 361 //extract(vShader, fShader); 362 } 363 364 void locate(in string name, in int value, in string type, in int num, in GLint location) { 365 _uniInt[type](location, value); 366 } 367 368 void locate(in string name, in float[] value, in string type, in int num, in GLint location) { 369 _uniFloatV[type](location, value, num); 370 } 371 372 private: 373 void init() { 374 _uniInt["1i"] = (location, value) { glUniform1i(location, value); }; 375 _uniFloatV["1fv"] = (location, value, num) { glUniform1fv(location, num, value.ptr); }; 376 _uniFloatV["2fv"] = (location, value, num) { glUniform2fv(location, num, value.ptr); }; 377 _uniFloatV["3fv"] = (location, value, num) { glUniform3fv(location, num, value.ptr); }; 378 _uniFloatV["4fv"] = (location, value, num) { glUniform4fv(location, num, value.ptr); }; 379 _uniFloatV["mat4fv"] = (location, value, num) { glUniformMatrix4fv(location, num, GL_FALSE, value.ptr); }; 380 } 381 382 // TODO ソースから判別 383 void extract(string vShader, string fShader) { 384 } 385 386 void delegate(in GLint, in int)[string] _uniInt; 387 //void delegate(int[])[string] _uniIntV; 388 //void delegate(float)[string] _uniFloat; 389 void delegate(in GLint, in float[], in int)[string] _uniFloatV; 390 } 391 392 deprecated class UniformLocation { 393 public: 394 this(in GLuint program) { 395 _program = program; 396 _uniform = new Uniform; 397 } 398 399 void attach(T)(in string name, in T value, in string type, in int num=1) { 400 _location = glGetUniformLocation(_program, cast(char*)name); 401 _uniform.locate(name, value, type, num, _location); 402 } 403 404 private: 405 Uniform _uniform; 406 GLuint _program; 407 GLint _location; 408 } 409 410 /************************ここまでいらない*************/ 411