1 module ecs_utils.gfx.renderer; 2 3 import bindbc.sdl; 4 5 import bubel.ecs.std; 6 7 //import ecs_utils.core : Backend; 8 import ecs_utils.gfx.buffer; 9 import ecs_utils.gfx.texture; 10 import ecs_utils.math.vector; 11 12 import bubel.ecs.block_allocator; 13 import bubel.ecs.vector; 14 version(WebAssembly)import glad.gl.gles2; 15 else version(Android)import glad.gl.gles2; 16 else import glad.gl.gl; 17 18 version = ver1; 19 /*version(ver5)version = vv2; 20 else version(ver6)version = vv2;*/ 21 22 extern(C) float sinf(float); 23 extern(C) float cosf(float); 24 25 enum RenderTechnique 26 { 27 simple,//1 28 simple_array,//2 29 vbo_batch,//3 30 instanced_attrib_divisor,//4 31 uniform_buffer,//5 32 uniform_buffer_indexed,//6 33 uniform_buffer_multi_draw,//7 34 uniform_buffer_instanced,//8 35 uniform_buffer_instanced_mapped_gl2,//9 36 uniform_buffer_instanced_mapped,//10 37 uniform_buffer_instanced_persistent_mapped,//11 38 uniform_buffer_instanced_persistent_mapped_coherent,//12 39 ssbo_instanced,//13 40 uniform_buffer_draw_indirect,//14 41 uniform_buffer_multi_draw_indirect,//15 42 uniform_buffer_multi_draw_indirect_arb_draw_parameters//16 43 } 44 45 struct Renderer 46 { 47 //static SDL_Renderer* main_sdl_renderer; 48 BlockAllocator allocator; 49 50 enum MaxObjects = 1024 * 64 * 4; 51 enum BufferUsage = GL_DYNAMIC_DRAW; 52 53 //SDL_Window* sdl_window; 54 //SDL_Renderer* sdl_renderer; 55 ivec2 resolution; 56 vec2 dres; 57 vec4 sdl_transform; 58 vec2 view_pos = vec2(-1,-1); 59 vec2 view_size = vec2(1,1); 60 61 enum block_size = 2^^16; 62 enum batch_size = block_size/68;//963;//16_384; 63 //uint[2] time_queries; 64 65 struct VertexBlock 66 { 67 enum max_items = batch_size;//963; 68 byte[] batch_vertices; 69 ushort[] batch_indices; 70 void* memory = null; 71 uint items = 0; 72 uint material_id; 73 uint texture_id; 74 } 75 76 Mutex* get_block_mutex; 77 Mutex* block_stack_mutex; 78 79 VertexBlock getBlock() 80 { 81 VertexBlock block; 82 get_block_mutex.lock(); 83 block.memory = allocator.getBlock(); 84 get_block_mutex.unlock(); 85 block.batch_vertices = (cast(byte*)block.memory)[0 .. VertexBlock.max_items * 4 * 14]; 86 block.batch_indices = (cast(ushort*)block.memory)[VertexBlock.max_items * 4 * 7 .. VertexBlock.max_items * (4 * 7 + 6)]; 87 return block; 88 } 89 90 Vector!VertexBlock blocks; 91 uint current_block = 0; 92 uint render_blocks = 0; 93 94 void pushBlock(VertexBlock block) 95 { 96 block_stack_mutex.lock(); 97 prepared_items += block.items; 98 blocks.add(block); 99 render_blocks++; 100 block_stack_mutex.unlock(); 101 } 102 103 bool isRemainingBlocks() 104 { 105 if(render_blocks <= current_block)return false; 106 return true; 107 } 108 109 VertexBlock fetchBlock() 110 { 111 block_stack_mutex.lock(); 112 VertexBlock block = blocks[current_block]; 113 current_block++; 114 block_stack_mutex.unlock(); 115 return block; 116 } 117 118 void freeBlocks() 119 { 120 /*block_stack_mutex.lock(); 121 render_blocks = 0; 122 current_block = 0; 123 foreach(VertexBlock block; blocks) 124 { 125 allocator.freeBlock(block.memory); 126 } 127 blocks.clear; 128 prepared_items=0; 129 draw_list.clear(); 130 block_stack_mutex.unlock();*/ 131 foreach(ref Thread thread; threads) 132 { 133 foreach(VertexBlock block; thread.filled_blocks) 134 { 135 allocator.freeBlock(block.memory); 136 } 137 thread.filled_blocks.clear(); 138 } 139 render_blocks = 0; 140 current_block = 0; 141 prepared_items = 0; 142 draw_list.clear(); 143 } 144 145 void pushData() 146 { 147 foreach(ref Thread thread; threads) 148 { 149 foreach(VertexBlock block; thread.filled_blocks) 150 { 151 uint items = block.items; 152 if(items + item_id >= MaxObjects)items = MaxObjects - item_id; 153 batch_vbo[0].bufferSubData(Buffer.BindTarget.array,items*4*14,item_id*4*14,block.batch_vertices.ptr); 154 batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,items*2*6,item_id*2*6,block.batch_indices.ptr); 155 draw_list.add(DrawCall(block.texture_id,block.material_id,item_id,items)); 156 item_id += items; 157 } 158 //thread.blocks.clear(); 159 } 160 //if(!isRemainingBlocks())return; 161 /* while(isRemainingBlocks()) 162 { 163 VertexBlock block = fetchBlock(); 164 uint items = block.items; 165 if(items + item_id >= MaxObjects)items = MaxObjects - item_id; 166 batch_vbo[0].bufferSubData(Buffer.BindTarget.array,items*4*14,item_id*4*14,block.batch_vertices.ptr); 167 batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,items*2*6,item_id*2*6,block.batch_indices.ptr); 168 draw_list.add(DrawCall(item_id,items)); 169 item_id += items; 170 }*/ 171 } 172 173 void pushThreadsBlocks() 174 { 175 foreach(i, ref Thread thread; threads) 176 { 177 //pushBlock(thread.block); 178 foreach(ref block; thread.blocks) 179 { 180 if(block.items > 0) 181 { 182 thread.filled_blocks.add(block); 183 block.items = 0; 184 } 185 } 186 //thread.blocks = getBlock(); 187 } 188 } 189 190 struct DrawData 191 { 192 Texture texture; 193 vec2 position; 194 vec2 size; 195 vec4 coords; 196 short depth = 0; 197 uint color = uint.max; 198 float angle = 0; 199 uint material_id = 0; 200 uint mesh_id = 0; 201 uint thread_id = 0; 202 } 203 204 struct Thread 205 { 206 //Vector!VertexBlock block; 207 RenderData[] render_list; 208 VertexBlock[] blocks; 209 Vector!VertexBlock filled_blocks; 210 } 211 Thread[] threads; 212 213 214 Buffer[2] ubos; 215 int block_alignment = 1; 216 int block_max_size = 16384; 217 218 struct IndirectDraw 219 { 220 uint count = 6; 221 uint instances = 1; 222 uint first_index = 0; 223 uint base_vertex = 0; 224 uint base_instance = 0; 225 } 226 227 Buffer[2] batch_vbo; 228 Buffer[2] batch_ibo; 229 230 ubyte[] batch_vertices; 231 ushort[] batch_indices; 232 233 Buffer indirect_buffer; 234 IndirectDraw[] indirect_block; 235 236 Buffer id_buffer; 237 238 int data_offset = 48; 239 int data_index; 240 ubyte[] uniform_block; 241 242 struct RenderData 243 { 244 Texture texture; 245 uint material_id; 246 uint mesh_id; 247 } 248 249 struct DrawCall 250 { 251 uint texture_id; 252 uint material_id; 253 uint start; 254 uint count; 255 } 256 257 Vector!DrawCall draw_list; 258 259 RenderData[] render_list; 260 uint item_id; 261 uint prepared_items; 262 263 uint[] multi_count; 264 uint[] multi_offset; 265 266 alias Technique = RenderTechnique; 267 268 __gshared Technique technique = Technique.vbo_batch; 269 void* data_ptr; 270 271 //import ecs_utils.core : RenderTechnique; 272 273 274 275 void initialize() 276 { 277 import ecs_utils.gfx.config; 278 //this.technique = __ecs_used_technique; 279 __initialize(this); 280 281 get_block_mutex = Mallocator.make!Mutex(); 282 block_stack_mutex = Mallocator.make!Mutex(); 283 get_block_mutex.initialize(); 284 block_stack_mutex.initialize(); 285 286 287 threads = Mallocator.makeArray!Thread(32); 288 foreach(ref Thread thread;threads) 289 { 290 //thread.blocks = getBlock(); 291 thread.blocks = Mallocator.makeArray!VertexBlock(GfxConfig.materials.length); 292 } 293 } 294 295 private static void __initialize_gl(ref Renderer this_) 296 { 297 with(this_) 298 { 299 //glGenQueries(2, time_queries.ptr); 300 301 version(WebAssembly) 302 { 303 304 } 305 else 306 { 307 glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &block_max_size); 308 glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &block_alignment); 309 } 310 311 //ubos[0].bufferStorage(1,64*MaxObjects,null); 312 313 switch(technique) 314 { 315 case Technique.simple: 316 uniform_block = Mallocator.makeArray!ubyte(64*MaxObjects); 317 data_ptr = uniform_block.ptr; 318 data_offset = cast(ushort)((data_offset + block_alignment - 1) & (-cast(int) block_alignment)); 319 break; 320 case Technique.simple_array: 321 goto case(Technique.simple); 322 case Technique.vbo_batch: 323 batch_vbo[0].create(); 324 batch_ibo[0].create(); 325 batch_vbo[0].bufferData(Buffer.BindTarget.array,14,4*MaxObjects,BufferUsage,null); 326 batch_ibo[0].bufferData(Buffer.BindTarget.element_array,2,6*MaxObjects,BufferUsage,null); 327 328 batch_vbo[1].create(); 329 batch_ibo[1].create(); 330 batch_vbo[1].bufferData(Buffer.BindTarget.array,14,4*MaxObjects,BufferUsage,null); 331 batch_ibo[1].bufferData(Buffer.BindTarget.element_array,2,6*MaxObjects,BufferUsage,null); 332 333 //batch_vertices = Mallocator.makeArray!ubyte(14*4*MaxObjects); 334 //batch_indices = Mallocator.makeArray!ushort(6*MaxObjects); 335 break; 336 case Technique.instanced_attrib_divisor: 337 goto case(Technique.uniform_buffer_indexed); 338 case Technique.uniform_buffer: 339 ubos[0].create(); 340 ubos[0].bufferData(Buffer.BindTarget.uniform,1,64*MaxObjects,BufferUsage,null); 341 ubos[1].create(); 342 ubos[1].bufferData(Buffer.BindTarget.uniform,1,64*MaxObjects,BufferUsage,null); 343 goto case(Technique.simple); 344 case Technique.uniform_buffer_indexed: 345 ubos[0].create(); 346 ubos[0].bufferData(Buffer.BindTarget.uniform,1,64*MaxObjects,BufferUsage,null); 347 ubos[1].create(); 348 ubos[1].bufferData(Buffer.BindTarget.uniform,1,64*MaxObjects,BufferUsage,null); 349 uniform_block = Mallocator.makeArray!ubyte(64*MaxObjects); 350 data_ptr = uniform_block.ptr; 351 break; 352 /*case Technique.uniform_buffer_multi_draw: 353 multi_count = Mallocator.makeArray!uint(992,6); 354 multi_offset = Mallocator.makeArray!uint(992,0); 355 356 { 357 uint[] indices = Mallocator.makeArray!uint(992); 358 scope(exit)Mallocator.dispose(indices); 359 foreach(i;0..992)indices[i]=i; 360 id_buffer.create(); 361 id_buffer.bufferData(uint.sizeof,992,BufferUsage,indices.ptr); 362 } 363 goto case(Technique.uniform_buffer_multi_draw_indirect_arb_draw_parameters);*/ 364 case Technique.uniform_buffer_instanced: 365 goto case(Technique.uniform_buffer_indexed); 366 case Technique.uniform_buffer_instanced_mapped_gl2: 367 ubos[0].create(); 368 ubos[0].bufferData(Buffer.BindTarget.uniform,1,512*MaxObjects,BufferUsage,null); 369 ubos[0].map(Buffer.BindTarget.uniform); 370 ubos[1].create(); 371 ubos[1].bufferData(Buffer.BindTarget.uniform,1,512*MaxObjects,BufferUsage,null); 372 ubos[1].map(Buffer.BindTarget.uniform); 373 data_ptr = ubos[0].mappedPointer(); 374 break; 375 case Technique.uniform_buffer_instanced_mapped: 376 ubos[0].create(); 377 ubos[0].bufferData(Buffer.BindTarget.uniform,1,64*MaxObjects,BufferUsage,null); 378 ubos[0].map(0, 64*MaxObjects, Buffer.BindTarget.uniform); 379 ubos[1].create(); 380 ubos[1].bufferData(Buffer.BindTarget.uniform,1,64*MaxObjects,BufferUsage,null); 381 ubos[1].map(0, 64*MaxObjects, Buffer.BindTarget.uniform); 382 data_ptr = ubos[0].mappedPointer(); 383 break; 384 /*case Technique.uniform_buffer_instanced_persistent_mapped: 385 ubos[0].create(); 386 ubos[0].bufferStorage(1,64*MaxObjects,null,Buffer.StorageFlagBits.write|Buffer.StorageFlagBits.persistent); 387 ubos[0].map(0, 64*MaxObjects, Buffer.BindTarget.uniform, Buffer.MapFlagBits.write | Buffer.MapFlagBits.persistent | Buffer.MapFlagBits.flush_explict); 388 data_ptr = ubos[0].mappedPointer(); 389 break; 390 case Technique.uniform_buffer_instanced_persistent_mapped_coherent: 391 ubos[0].create(); 392 ubos[0].bufferStorage(1,64*MaxObjects,null,Buffer.StorageFlagBits.write|Buffer.StorageFlagBits.persistent|Buffer.StorageFlagBits.coherent); 393 ubos[0].map(0, 64*MaxObjects, Buffer.BindTarget.uniform, Buffer.MapFlagBits.write | Buffer.MapFlagBits.persistent | Buffer.MapFlagBits.flush_explict | Buffer.MapFlagBits.coherent); 394 ubos[1].create(); 395 ubos[1].bufferStorage(1,64*MaxObjects,null,Buffer.StorageFlagBits.write|Buffer.StorageFlagBits.persistent|Buffer.StorageFlagBits.coherent); 396 ubos[1].map(0, 64*MaxObjects, Buffer.BindTarget.uniform, Buffer.MapFlagBits.write | Buffer.MapFlagBits.persistent | Buffer.MapFlagBits.flush_explict | Buffer.MapFlagBits.coherent); 397 data_ptr = ubos[0].mappedPointer(); 398 break; 399 case Technique.ssbo_instanced: 400 goto case(Technique.uniform_buffer_indexed); 401 case Technique.uniform_buffer_draw_indirect: 402 indirect_block = Mallocator.makeArray!IndirectDraw(1); 403 indirect_buffer.create(); 404 indirect_buffer.bufferData(IndirectDraw.sizeof,1,BufferUsage,indirect_block.ptr); 405 indirect_buffer.bind(Buffer.BindTarget.indirect); 406 goto case(Technique.uniform_buffer); 407 case Technique.uniform_buffer_multi_draw_indirect: 408 goto case(Technique.uniform_buffer_multi_draw_indirect_arb_draw_parameters); 409 case Technique.uniform_buffer_multi_draw_indirect_arb_draw_parameters: 410 indirect_block = Mallocator.makeArray!IndirectDraw(992); 411 foreach(i;0..992) 412 { 413 IndirectDraw* idraw = &indirect_block[i]; 414 idraw.base_instance = i; 415 } 416 indirect_buffer.create(); 417 indirect_buffer.bufferData(IndirectDraw.sizeof,992,BufferUsage,indirect_block.ptr); 418 indirect_buffer.bind(Buffer.BindTarget.indirect); 419 goto case(Technique.uniform_buffer_indexed);*/ 420 default:break; 421 }//*/ 422 423 // if(batching)data_offset = cast(ushort)((data_offset + block_alignment - 1) & (-cast(int) block_alignment)); 424 //data_offset = cast(ushort)((data_offset + block_alignment - 1) & (-cast(int) block_alignment)); 425 426 /*version(ver4){} 427 else version(ver5){} 428 else version(ver6){} 429 else data_offset = cast(ushort)((data_offset + block_alignment - 1) & (-cast(int) block_alignment));//*/ 430 //data_offset = (data_offset + block_alignment - 1) - data_offset % block_alignment; 431 432 render_list = Mallocator.makeArray!RenderData(MaxObjects); 433 434 SDL_Log("Uniform block alignment: %u",block_alignment); 435 SDL_Log("Uniform block max size: %u",block_max_size); 436 SDL_Log("Data offset: %u",data_offset); 437 438 allocator = BlockAllocator(block_size, 32); 439 } 440 } 441 442 private static void __initialize_sdl(ref Renderer this_) 443 { 444 445 } 446 447 //void draw(Texture tex, vec2 pos, vec2 size, vec4 coords, short depth = 0, uint color = uint.max, float angle = 0, uint material_id = 0, uint mesh_id = 0, uint thread_id = 0) 448 void draw(scope ref const(DrawData) data) 449 { 450 if(prepared_items >= MaxObjects)return; 451 if(threads[data.thread_id].blocks.length <= data.material_id)return; 452 __draw(this,data);//tex,pos,size,coords,depth,color,angle,material_id,mesh_id,thread_id); 453 } 454 455 //private static void __draw_sdl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) 456 private static void __draw_sdl(ref Renderer this_, scope ref const(DrawData) data) 457 { 458 /*with(this_) 459 { 460 SDL_Rect rect = SDL_Rect(cast(int)(coords.x*tex.data.size.x),cast(int)(coords.y*tex.data.size.y),cast(int)(coords.z*tex.data.size.x),cast(int)(coords.w*tex.data.size.y)); 461 SDL_Rect rect2 = SDL_Rect(cast(int)((pos.x-size.x*0.5)), 462 cast(int)(resolution.y - pos.y - size.y*0.5), 463 cast(int)(size.x), 464 cast(int)(size.y)); 465 466 SDL_RenderCopyEx(sdl_renderer, 467 tex.data.texture, 468 &rect, 469 &rect2, 470 angle*360, 471 null, 472 SDL_FLIP_NONE); 473 }*/ 474 } 475 476 // private static void __draw_gl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) 477 private static void __draw_gl(ref Renderer this_, scope ref const(DrawData) data) 478 { 479 //import core.stdc.string; 480 with(this_) 481 { 482 //pos += view_pos; 483 vec2 pos = void; 484 vec2 size = void; 485 size.x = data.size.x * view_size.x; 486 size.y = data.size.y * view_size.y; 487 pos.x = data.position.x * view_size.x + view_pos.x; 488 pos.y = data.position.y * view_size.y + view_pos.y;//*/ 489 490 /*version(ver6)void* ptr = ubos[0].mappedPointer() + data_index; 491 else void* ptr = uniform_block.ptr + data_index;*/ 492 if(data_ptr is null)return; 493 void* ptr = data_ptr + data_index; 494 if(data.angle == 0) 495 { 496 *cast(float*)ptr = size.x; 497 *cast(float*)(ptr+4) = 0; 498 *cast(float*)(ptr+8) = 0; 499 *cast(float*)(ptr+12) = size.y; 500 } 501 else 502 { 503 //import core.stdc.math; 504 float sinn = sinf(data.angle); 505 float coss = cosf(data.angle); 506 *cast(float*)ptr = coss * size.x; 507 *cast(float*)(ptr+4) = -sinn * size.y; 508 *cast(float*)(ptr+8) = sinn * size.x; 509 *cast(float*)(ptr+12) = coss * size.y; 510 } 511 512 //memcpy(ptr,); 513 memcpy(ptr+16,pos.data.ptr,8); 514 memcpy(ptr+32,data.coords.data.ptr,16); 515 516 //render_list[item_id] = RenderData(tex,material_id,mesh_id); 517 render_list[item_id].texture = *cast(Texture*)&data.texture; 518 render_list[item_id].material_id = data.material_id; 519 render_list[item_id].mesh_id = data.mesh_id; 520 521 data_index += data_offset; 522 item_id++; 523 prepared_items++; 524 } 525 } 526 527 // private static void __draw_gl_vbo_batch(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id = 0) 528 private static void __draw_gl_vbo_batch(ref Renderer this_, scope ref const(DrawData) data) 529 { 530 import ecs_utils.gfx.config; 531 532 //import core.stdc.string; 533 with(this_) 534 { 535 uint thread_id = data.thread_id; 536 //if(item_id >= MaxObjects)return; 537 //pos += view_pos; 538 Thread* thread = &threads[thread_id]; 539 VertexBlock* block; 540 assert(thread.blocks.length > data.material_id); 541 block = &thread.blocks[data.material_id]; 542 if(block.items == 0) 543 { 544 thread.blocks[data.material_id] = getBlock(); 545 block = &thread.blocks[data.material_id]; 546 block.material_id = data.material_id; 547 } 548 else if(block.items >= VertexBlock.max_items) 549 { 550 //pushBlock(thread.block); 551 prepared_items += block.items; 552 thread.filled_blocks.add(*block); 553 thread.blocks[data.material_id] = getBlock(); 554 block = &thread.blocks[data.material_id]; 555 block.material_id = data.material_id; 556 } 557 558 short[3] mem = [data.depth, *cast(short*)&data.color, *(cast(short*)&data.color + 1)]; 559 560 vec2 pos = void; 561 vec2 size = void; 562 pos.x = data.position.x * view_size.x + view_pos.x; 563 pos.y = data.position.y * view_size.y + view_pos.y;//*/ 564 565 /*void* ptr = data_ptr + data_index; 566 *cast(float*)ptr = size.x; 567 *cast(float*)(ptr+4) = 0; 568 *cast(float*)(ptr+8) = 0; 569 *cast(float*)(ptr+12) = size.y; 570 //memcpy(ptr,); 571 memcpy(ptr+16,pos.data.ptr,8); 572 memcpy(ptr+32,coords.data.ptr,16);*/ 573 574 short[] verts = (cast(short*)block.batch_vertices.ptr)[0..block.batch_vertices.length>>1]; 575 uint item_id = block.items; 576 577 uint mesh_id = data.mesh_id; 578 vec4 coords = data.coords; 579 580 if(data.angle == 0) 581 { 582 size.x = data.size.x * view_size.x; 583 size.y = data.size.y * view_size.y; 584 585 verts[item_id*28] = cast(short)((GfxConfig.meshes[mesh_id].vertices[0] * size.x + pos.x) * 8191); 586 verts[item_id*28+1] = cast(short)((GfxConfig.meshes[mesh_id].vertices[1] * size.y + pos.y) * 8191); 587 verts[item_id*28+2] = cast(short)((GfxConfig.meshes[mesh_id].vertices[2] * coords.z + coords.x)*32767); 588 verts[item_id*28+3] = cast(short)((GfxConfig.meshes[mesh_id].vertices[3] * coords.w + coords.y)*32767); 589 memcpy(verts.ptr+item_id*28+4,mem.ptr,6); 590 591 592 verts[item_id*28+7] = cast(short)((GfxConfig.meshes[mesh_id].vertices[4] * size.x + pos.x) * 8191); 593 verts[item_id*28+8] = cast(short)((GfxConfig.meshes[mesh_id].vertices[5] * size.y + pos.y) * 8191); 594 verts[item_id*28+9] = cast(short)((GfxConfig.meshes[mesh_id].vertices[6] * coords.z + coords.x)*32767); 595 verts[item_id*28+10] = cast(short)((GfxConfig.meshes[mesh_id].vertices[7] * coords.w + coords.y)*32767); 596 memcpy(verts.ptr+item_id*28+11,mem.ptr,6); 597 598 599 verts[item_id*28+14] = cast(short)((GfxConfig.meshes[mesh_id].vertices[8] * size.x + pos.x) * 8191); 600 verts[item_id*28+15] = cast(short)((GfxConfig.meshes[mesh_id].vertices[9] * size.y + pos.y) * 8191); 601 verts[item_id*28+16] = cast(short)((GfxConfig.meshes[mesh_id].vertices[10] * coords.z + coords.x)*32767); 602 verts[item_id*28+17] = cast(short)((GfxConfig.meshes[mesh_id].vertices[11] * coords.w + coords.y)*32767); 603 memcpy(verts.ptr+item_id*28+18,mem.ptr,6); 604 605 606 verts[item_id*28+21] = cast(short)((GfxConfig.meshes[mesh_id].vertices[12] * size.x + pos.x) * 8191); 607 verts[item_id*28+22] = cast(short)((GfxConfig.meshes[mesh_id].vertices[13] * size.y + pos.y) * 8191); 608 verts[item_id*28+23] = cast(short)((GfxConfig.meshes[mesh_id].vertices[14] * coords.z + coords.x)*32767); 609 verts[item_id*28+24] = cast(short)((GfxConfig.meshes[mesh_id].vertices[15] * coords.w + coords.y)*32767); 610 memcpy(verts.ptr+item_id*28+25,mem.ptr,6); 611 } 612 else 613 { 614 //import core.stdc.math; 615 float angle = data.angle; 616 float sinx = sinf(angle) * data.size.x * view_size.y; 617 float cosx = cosf(angle) * data.size.x * view_size.x; 618 float siny = sinf(angle) * data.size.y * view_size.x; 619 float cosy = cosf(angle) * data.size.y * view_size.y; 620 621 /*batch_vertices[item_id*28] = GfxConfig.meshes[mesh_id].vertices[0] * size.x; 622 batch_vertices[item_id*28+1] = GfxConfig.meshes[mesh_id].vertices[1] * size.y; 623 batch_vertices[item_id*28+4] = GfxConfig.meshes[mesh_id].vertices[4] * size.x; 624 batch_vertices[item_id*28+5] = GfxConfig.meshes[mesh_id].vertices[5] * size.y; 625 batch_vertices[item_id*28+8] = GfxConfig.meshes[mesh_id].vertices[8] * size.x; 626 batch_vertices[item_id*28+9] = GfxConfig.meshes[mesh_id].vertices[9] * size.y; 627 batch_vertices[item_id*28+12] = GfxConfig.meshes[mesh_id].vertices[12] * size.x; 628 batch_vertices[item_id*28+13] = GfxConfig.meshes[mesh_id].vertices[13] * size.y;*/ 629 630 verts[item_id*28] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[0] * cosx + GfxConfig.meshes[mesh_id].vertices[1] * siny) + pos.x) * 8191); 631 verts[item_id*28+1] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[1] * cosy - GfxConfig.meshes[mesh_id].vertices[0] * sinx) + pos.y) * 8191); 632 verts[item_id*28+2] = cast(short)((GfxConfig.meshes[mesh_id].vertices[2] * coords.z + coords.x)*32767); 633 verts[item_id*28+3] = cast(short)((GfxConfig.meshes[mesh_id].vertices[3] * coords.w + coords.y)*32767); 634 memcpy(verts.ptr+item_id*28+4,mem.ptr,6); 635 636 637 verts[item_id*28+7] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[4] * cosx + GfxConfig.meshes[mesh_id].vertices[5] * siny) + pos.x) * 8191); 638 verts[item_id*28+8] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[5] * cosy - GfxConfig.meshes[mesh_id].vertices[4] * sinx) + pos.y) * 8191); 639 verts[item_id*28+9] = cast(short)((GfxConfig.meshes[mesh_id].vertices[6] * coords.z + coords.x)*32767); 640 verts[item_id*28+10] = cast(short)((GfxConfig.meshes[mesh_id].vertices[7] * coords.w + coords.y)*32767); 641 memcpy(verts.ptr+item_id*28+11,mem.ptr,6); 642 643 644 verts[item_id*28+14] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[8] * cosx + GfxConfig.meshes[mesh_id].vertices[9] * siny) + pos.x) * 8191); 645 verts[item_id*28+15] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[9] * cosy - GfxConfig.meshes[mesh_id].vertices[8] * sinx) + pos.y) * 8191); 646 verts[item_id*28+16] = cast(short)((GfxConfig.meshes[mesh_id].vertices[10] * coords.z + coords.x)*32767); 647 verts[item_id*28+17] = cast(short)((GfxConfig.meshes[mesh_id].vertices[11] * coords.w + coords.y)*32767); 648 memcpy(verts.ptr+item_id*28+18,mem.ptr,6); 649 650 651 verts[item_id*28+21] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[12] * cosx + GfxConfig.meshes[mesh_id].vertices[13] * siny) + pos.x) * 8191); 652 verts[item_id*28+22] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[13] * cosy - GfxConfig.meshes[mesh_id].vertices[12] * sinx) + pos.y) * 8191); 653 verts[item_id*28+23] = cast(short)((GfxConfig.meshes[mesh_id].vertices[14] * coords.z + coords.x)*32767); 654 verts[item_id*28+24] = cast(short)((GfxConfig.meshes[mesh_id].vertices[15] * coords.w + coords.y)*32767); 655 memcpy(verts.ptr+item_id*28+25,mem.ptr,6); 656 } 657 658 /*verts[item_id*28+2] = cast(short)((GfxConfig.meshes[mesh_id].vertices[2] * coords.z + coords.x)*32767); 659 verts[item_id*28+3] = cast(short)((GfxConfig.meshes[mesh_id].vertices[3] * coords.w + coords.y)*32767); 660 verts[item_id*28+9] = cast(short)((GfxConfig.meshes[mesh_id].vertices[6] * coords.z + coords.x)*32767); 661 verts[item_id*28+10] = cast(short)((GfxConfig.meshes[mesh_id].vertices[7] * coords.w + coords.y)*32767); 662 verts[item_id*28+16] = cast(short)((GfxConfig.meshes[mesh_id].vertices[10] * coords.z + coords.x)*32767); 663 verts[item_id*28+17] = cast(short)((GfxConfig.meshes[mesh_id].vertices[11] * coords.w + coords.y)*32767); 664 verts[item_id*28+23] = cast(short)((GfxConfig.meshes[mesh_id].vertices[14] * coords.z + coords.x)*32767); 665 verts[item_id*28+24] = cast(short)((GfxConfig.meshes[mesh_id].vertices[15] * coords.w + coords.y)*32767);*/ 666 667 /*verts[item_id*28+4] = depth; 668 verts[item_id*28+11] = depth; 669 verts[item_id*28+18] = depth; 670 verts[item_id*28+25] = depth; 671 672 *cast(uint*)&verts[item_id*28+5] = color; 673 *cast(uint*)&verts[item_id*28+12] = color; 674 *cast(uint*)&verts[item_id*28+19] = color; 675 *cast(uint*)&verts[item_id*28+26] = color; 676 677 memcpy(verts.ptr+item_id*28+4,mem.ptr,6); 678 memcpy(verts.ptr+item_id*28+11,mem.ptr,6); 679 memcpy(verts.ptr+item_id*28+18,mem.ptr,6); 680 memcpy(verts.ptr+item_id*28+25,mem.ptr,6);*/ 681 682 uint ind_id = (item_id % batch_size)*4; 683 684 ushort[] indices = block.batch_indices; 685 686 indices[item_id*6] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[0] + ind_id); 687 indices[item_id*6+1] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[1] + ind_id); 688 indices[item_id*6+2] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[2] + ind_id); 689 indices[item_id*6+3] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[3] + ind_id); 690 indices[item_id*6+4] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[4] + ind_id); 691 indices[item_id*6+5] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[5] + ind_id); 692 693 //render_list[item_id] = RenderData(tex,material_id,mesh_id); 694 //render_list[item_id].texture = tex; 695 //render_list[item_id].material_id = material_id; 696 //render_list[item_id].mesh_id = mesh_id; 697 698 //data_index += 1;//data_offset; 699 block.items++; 700 } 701 } 702 703 void clear() 704 { 705 __clear(this); 706 } 707 708 private static void __clear_sdl(ref Renderer this_) 709 { 710 //SDL_RenderClear(this_.sdl_renderer); 711 } 712 713 private static void __clear_gl(ref Renderer this_) 714 { 715 glClearColor(0,0,0,0); 716 glViewport(0,0,this_.resolution.x,this_.resolution.y); 717 glDepthMask(1); 718 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 719 //glDisable(GL_DEPTH_TEST); 720 glEnable(GL_DEPTH_TEST); 721 glDisable(GL_CULL_FACE); 722 glDepthFunc(GL_LESS); 723 724 version(WebAssembly) 725 { 726 glDepthRangef(0,1); 727 } 728 else version(Android) 729 { 730 glDepthRangef(0,1); 731 } 732 else 733 { 734 glDepthRange(0,1); 735 } 736 //glDepthRange(0,1); 737 //glClearDepth(1); 738 } 739 740 void present() 741 { 742 __present(this); 743 } 744 745 private static void __present_sdl(ref Renderer this_) 746 { 747 //+SDL_RenderPresent(this_.sdl_renderer); 748 } 749 750 private static void __present_gl(ref Renderer this_) 751 { 752 753 this_.pushThreadsBlocks(); 754 this_.pushData(); 755 756 glViewport(0,0,this_.resolution.x,this_.resolution.y); 757 //glEnable(GL_ALPHA_TEST); 758 //glAlphaFunc(GL_GREATER, 0.01); 759 glEnableVertexAttribArray(0); 760 glEnableVertexAttribArray(1); 761 import ecs_utils.gfx.config; 762 with(this_) 763 { 764 bool instanced = false; 765 bool indirect = false; 766 bool multi_draw = false; 767 Buffer.BindTarget buffer_target = Buffer.BindTarget.uniform; 768 769 switch(technique) 770 { 771 case Technique.simple: 772 break; 773 case Technique.simple_array: 774 break; 775 case Technique.vbo_batch: 776 //if(data_index){ 777 //batch_vbo[0].bufferSubData(Buffer.BindTarget.array,item_id*4*14,0,batch_vertices.ptr); 778 //batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,item_id*6*2,0,batch_indices.ptr); 779 780 batch_vbo[0].bind(Buffer.BindTarget.array); 781 batch_ibo[0].bind(Buffer.BindTarget.element_array); 782 783 //glVertexAttribPointer(0,2,GL_SHORT,true,14,null); 784 //glVertexAttribPointer(1,2,GL_SHORT,true,14,cast(void*)4);//} 785 glEnableVertexAttribArray(2); 786 glEnableVertexAttribArray(3); 787 //glVertexAttribPointer(2,1,GL_SHORT,true,14,cast(void*)6);//} 788 break; 789 case Technique.instanced_attrib_divisor: 790 ubos[0].bufferSubData(Buffer.BindTarget.uniform,data_index,0,uniform_block.ptr); 791 ubos[0].bind(Buffer.BindTarget.uniform); 792 glEnableVertexAttribArray(2); 793 glEnableVertexAttribArray(3); 794 glEnableVertexAttribArray(4); 795 796 glVertexAttribPointer(2,4,GL_FLOAT,false,48,null); 797 glVertexAttribPointer(3,4,GL_FLOAT,false,48,cast(void*)16); 798 glVertexAttribPointer(4,4,GL_FLOAT,false,48,cast(void*)32); 799 glVertexAttribDivisor(2,1); 800 glVertexAttribDivisor(3,1); 801 glVertexAttribDivisor(4,1); 802 //ubos[0].bindRange(Buffer.BindTarget.uniform,0,0,block_max_size); 803 break; 804 case Technique.uniform_buffer: 805 //ubos[0].bufferData(1,64*MaxObjects,BufferUsage,null); 806 /*if(data_index)*/ubos[0].bufferSubData(Buffer.BindTarget.uniform,data_index,0,uniform_block.ptr); 807 break; 808 case Technique.uniform_buffer_indexed: 809 ubos[0].bindRange(Buffer.BindTarget.uniform,0,0,block_max_size); 810 goto case(Technique.uniform_buffer); 811 case Technique.uniform_buffer_multi_draw: 812 id_buffer.bind(Buffer.BindTarget.array); 813 glEnableVertexAttribArray(2); 814 815 glVertexAttribIPointer(2,1,GL_UNSIGNED_INT,cast(uint)uint.sizeof,cast(void*)0); 816 glVertexAttribDivisor(2,1); 817 multi_draw = true; 818 goto case(Technique.uniform_buffer_instanced); 819 case Technique.uniform_buffer_instanced: 820 instanced = true; 821 goto case(Technique.uniform_buffer); 822 case Technique.uniform_buffer_instanced_mapped_gl2: 823 instanced = true; 824 ubos[0].unmap(Buffer.BindTarget.uniform); 825 break; 826 case Technique.uniform_buffer_instanced_mapped: 827 instanced = true; 828 ubos[0].flush(0,data_index,Buffer.BindTarget.uniform); 829 ubos[0].unmap(Buffer.BindTarget.uniform); 830 break; 831 /*case Technique.uniform_buffer_instanced_persistent_mapped: 832 instanced = true; 833 ubos[0].flush(0,data_index,Buffer.BindTarget.uniform); 834 //glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 835 break; 836 case Technique.uniform_buffer_instanced_persistent_mapped_coherent: 837 instanced = true; 838 break; 839 //ubos[0].flush(0,data_index,Buffer.BindTarget.uniform); 840 //goto case(Technique.uniform_buffer_instanced_mapped); 841 case Technique.ssbo_instanced: 842 //buffer_target = Buffer.BindTarget.shader_storage; 843 ubos[0].bindRange(Buffer.BindTarget.shader_storage,0,0,48*MaxObjects); 844 goto case(Technique.uniform_buffer_instanced); 845 case Technique.uniform_buffer_draw_indirect: 846 goto case(Technique.uniform_buffer); 847 case Technique.uniform_buffer_multi_draw_indirect: 848 indirect_buffer.bind(Buffer.BindTarget.array); 849 glEnableVertexAttribArray(2); 850 851 glVertexAttribIPointer(2,1,GL_UNSIGNED_INT,cast(uint)IndirectDraw.sizeof,cast(void*)(4*uint.sizeof)); 852 glVertexAttribDivisor(2,1); 853 goto case(Technique.uniform_buffer_multi_draw_indirect_arb_draw_parameters); 854 case Technique.uniform_buffer_multi_draw_indirect_arb_draw_parameters: 855 indirect = true; 856 goto case(Technique.uniform_buffer_instanced);*/ 857 default:break; 858 } 859 860 data_index = 0; 861 862 int mesh_id = -1; 863 int material_id = -1; 864 int ubo_start = -1; 865 Texture texture; 866 uint item_ubo_id = 0; 867 868 /*Buffer tmpb = ubos[0]; 869 ubos[0] = ubos[1]; 870 ubos[1] = tmpb; 871 872 tmpb = batch_vbo[0]; 873 batch_vbo[0] = batch_vbo[1]; 874 batch_vbo[1] = tmpb; 875 876 tmpb = batch_ibo[0]; 877 batch_ibo[0] = batch_ibo[1]; 878 batch_ibo[1] = tmpb;//*/ 879 //glFinish(); 880 881 //glBeginQuery(GL_TIME_ELAPSED, time_queries[0]); 882 if(technique == Technique.vbo_batch) 883 { 884 //uint items = item_id/batch_size+1; 885 foreach(i; 0..draw_list.length) 886 { 887 if(material_id != draw_list[i].material_id) 888 { 889 material_id = draw_list[i].material_id; 890 GfxConfig.materials[material_id].bind(); 891 float[3*4] data = [1,0,0,1,0,0,0,0,0,0,1,1]; 892 GfxConfig.materials[material_id].pushUniforms(data.ptr); 893 } 894 if(texture.data != render_list[i].texture.data) 895 { 896 texture.data = render_list[i].texture.data; 897 render_list[i].texture.bind(); 898 } 899 900 /*uint instance_count = batch_size; 901 if((i+1)*batch_size > item_id) 902 { 903 instance_count = item_id%batch_size; 904 }*/ 905 906 // glVertexAttribPointer(0,2,GL_FLOAT,false,16,cast(void*)(i*batch_size*4*16)); 907 // glVertexAttribPointer(1,2,GL_FLOAT,false,16,cast(void*)(i*batch_size*4*16+8)); 908 glVertexAttribPointer(0,2,GL_SHORT,true,14,cast(void*)(draw_list[i].start*4*14)); 909 glVertexAttribPointer(1,2,GL_SHORT,true,14,cast(void*)(draw_list[i].start*4*14+4)); 910 glVertexAttribPointer(2,1,GL_SHORT,true,14,cast(void*)(draw_list[i].start*4*14+8)); 911 glVertexAttribPointer(3,4,GL_UNSIGNED_BYTE,true,14,cast(void*)(draw_list[i].start*4*14+10)); 912 913 glDrawElements(GL_TRIANGLES,draw_list[i].count*6,GL_UNSIGNED_SHORT,cast(void*)(draw_list[i].start*6*2)); 914 915 //glDrawElementsBaseVertex(GL_TRIANGLES,instance_count*6,GL_UNSIGNED_SHORT,cast(void*)(i*16_384*6*2),i*16_384*4); 916 } 917 } 918 else if(technique == Technique.ssbo_instanced || technique == Technique.instanced_attrib_divisor) 919 { 920 if(mesh_id != render_list[0].mesh_id) 921 { 922 mesh_id = render_list[0].mesh_id; 923 GfxConfig.meshes[mesh_id].bind(); 924 } 925 if(material_id != render_list[0].material_id) 926 { 927 material_id = render_list[0].material_id; 928 GfxConfig.materials[material_id].bind(); 929 } 930 if(texture.data != render_list[0].texture.data) 931 { 932 texture.data = render_list[0].texture.data; 933 render_list[0].texture.bind(); 934 } 935 glDrawArraysInstanced(GL_TRIANGLE_STRIP,0,4,item_id); 936 //glDrawElementsInstanced(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,null,item_id); 937 } 938 else if(instanced) 939 { 940 uint items = item_id/992+1; 941 foreach(i; 0..items) 942 { 943 if(mesh_id != render_list[i].mesh_id) 944 { 945 mesh_id = render_list[i].mesh_id; 946 GfxConfig.meshes[mesh_id].bind(); 947 } 948 if(material_id != render_list[i].material_id) 949 { 950 material_id = render_list[i].material_id; 951 GfxConfig.materials[material_id].bind(); 952 } 953 if(texture.data != render_list[i].texture.data) 954 { 955 texture.data = render_list[0].texture.data; 956 render_list[i].texture.bind(); 957 } 958 ubos[0].bindRange(buffer_target,0,data_index,block_max_size); 959 960 uint instance_count = 992; 961 if(i*992 > item_id) 962 { 963 instance_count = i*992 - item_id; 964 } 965 966 /*if(indirect)glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, cast(void*)0, instance_count, 0); 967 else if(multi_draw)glMultiDrawElements(GL_TRIANGLES,cast(int*)multi_count.ptr,GL_UNSIGNED_SHORT,cast(void**)multi_offset.ptr,instance_count); 968 //glMultiDrawElementsBaseVertex(GL_TRIANGLES,cast(int*)multi_count.ptr,GL_UNSIGNED_SHORT,cast(void**)multi_offset.ptr,instance_count,cast(int*)multi_offset.ptr); 969 else */glDrawElementsInstanced(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,null,instance_count); 970 //glDrawArraysInstanced(GL_TRIANGLES,0,6,instance_count); 971 data_index += data_offset * 992; 972 } 973 } 974 else 975 foreach(item; render_list[0..item_id]) 976 { 977 if(mesh_id != item.mesh_id) 978 { 979 mesh_id = item.mesh_id; 980 GfxConfig.meshes[mesh_id].bind(); 981 } 982 if(material_id != item.material_id) 983 { 984 material_id = item.material_id; 985 GfxConfig.materials[material_id].bind(); 986 GfxConfig.materials[material_id].pushBindings(); 987 } 988 if(texture.data != item.texture.data) 989 { 990 texture.data = render_list[0].texture.data; 991 item.texture.bind(); 992 } 993 994 switch(technique) 995 { 996 case Technique.simple: 997 /*glUniform4f(0, *cast(float*)&uniform_block[data_index], *cast(float*)&uniform_block[data_index+4], *cast(float*)&uniform_block[data_index+8], *cast(float*)&uniform_block[data_index+12]); 998 glUniform4f(1, *cast(float*)&uniform_block[data_index+16], *cast(float*)&uniform_block[data_index+20], *cast(float*)&uniform_block[data_index+24], *cast(float*)&uniform_block[data_index+28]); 999 glUniform4f(2, *cast(float*)&uniform_block[data_index+32], *cast(float*)&uniform_block[data_index+36], *cast(float*)&uniform_block[data_index+40], *cast(float*)&uniform_block[data_index+44]); 1000 */ 1001 GfxConfig.materials[material_id].pushUniforms(&uniform_block[data_index]);break; 1002 case Technique.simple_array: 1003 glUniform4fv(0,12,cast(float*)(uniform_block.ptr+data_index)); 1004 break; 1005 case Technique.uniform_buffer: 1006 ubos[0].bindRange(Buffer.BindTarget.uniform,0,data_index,data_offset); 1007 break; 1008 /*case Technique.uniform_buffer_draw_indirect: 1009 ubos[0].bindRange(Buffer.BindTarget.uniform,0,data_index,data_offset); 1010 glDrawElementsIndirect(GL_TRIANGLES,GL_UNSIGNED_SHORT,null); 1011 data_index += data_offset; 1012 continue;*/ 1013 case Technique.uniform_buffer_indexed: 1014 if(item_ubo_id >= 992) 1015 { 1016 item_ubo_id = 0; 1017 ubo_start = data_index; 1018 ubos[0].bindRange(Buffer.BindTarget.uniform,0,ubo_start,block_max_size); 1019 } 1020 glUniform1i(0,item_ubo_id++); 1021 break; 1022 default:break; 1023 }//*/ 1024 1025 /*version(ver3)ubos[0].bindRange(Buffer.BindTarget.uniform,0,data_index,data_offset); 1026 else version(ver1) 1027 { 1028 glUniform4f(0, *cast(float*)&uniform_block[data_index], *cast(float*)&uniform_block[data_index+4], *cast(float*)&uniform_block[data_index+8], *cast(float*)&uniform_block[data_index+12]); 1029 glUniform4f(1, *cast(float*)&uniform_block[data_index+16], *cast(float*)&uniform_block[data_index+20], *cast(float*)&uniform_block[data_index+24], *cast(float*)&uniform_block[data_index+28]); 1030 glUniform4f(2, *cast(float*)&uniform_block[data_index+32], *cast(float*)&uniform_block[data_index+36], *cast(float*)&uniform_block[data_index+40], *cast(float*)&uniform_block[data_index+44]); 1031 } 1032 else version(ver2)glUniform4fv(0,12,cast(float*)(uniform_block.ptr+data_index)); 1033 else version(ver4) 1034 { 1035 if(item_ubo_id >= 992) 1036 { 1037 item_ubo_id = 0; 1038 ubo_start = data_index; 1039 ubos[0].bindRange(Buffer.BindTarget.uniform,0,ubo_start,block_max_size); 1040 } 1041 glUniform1i(0,item_ubo_id++); 1042 }//*/ 1043 1044 glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,null); 1045 //glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 1046 data_index += data_offset; 1047 } 1048 //glEndQuery(GL_TIME_ELAPSED); 1049 //uint tmpq = time_queries[0]; 1050 //time_queries[0] = time_queries[1]; 1051 //time_queries[1] = tmpq; 1052 /*Buffer tmpb = ubos[0]; 1053 ubos[0] = ubos[1]; 1054 ubos[1] = tmpb;//*/ 1055 1056 data_index = 0; 1057 //data_offset = 0; 1058 item_id = 0; 1059 //SDL_GL_SwapWindow(sdl_window); 1060 //glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); 1061 //version(ver6)ubos[0].map(0, 64*MaxObjects, Buffer.BindTarget.uniform); 1062 //ubos[0].map(Buffer.BindTarget.uniform); 1063 1064 switch(technique) 1065 { 1066 case Technique.uniform_buffer_instanced_mapped_gl2: 1067 ubos[0].map(Buffer.BindTarget.uniform); 1068 //data_ptr = ubos[0].mappedPointer(); 1069 break; 1070 case Technique.uniform_buffer_instanced_mapped: 1071 ubos[0].map(0, 64*MaxObjects, Buffer.BindTarget.uniform); 1072 //data_ptr = ubos[0].mappedPointer(); 1073 break; 1074 default:break; 1075 } 1076 1077 if(ubos[0].data && ubos[0].mappedPointer) 1078 { 1079 data_ptr = ubos[0].mappedPointer; 1080 } 1081 1082 /*switch(technique) 1083 { 1084 case Technique.simple: 1085 case Technique.simple_array: 1086 case Technique.uniform_buffer: 1087 case Technique.uniform_buffer_indexed: 1088 case Technique.uniform_buffer_instanced: 1089 case Technique.uniform_buffer_instanced_mapped: 1090 case Technique.uniform_buffer_instanced_persistent_mapped: 1091 default:break; 1092 }*/ 1093 } 1094 glDisableVertexAttribArray(0); 1095 glDisableVertexAttribArray(1); 1096 glDisableVertexAttribArray(2); 1097 glDisableVertexAttribArray(3); 1098 this_.freeBlocks(); 1099 /*glUseProgram(0); 1100 glBindBuffer(GL_ARRAY_BUFFER, 0); 1101 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);*/ 1102 //glDisable(GL_ALPHA_TEST); 1103 } 1104 1105 void resize(ivec2 size) 1106 { 1107 resolution = size; 1108 dres = vec2(1.0/cast(float)size.x,1.0/cast(float)size.y); 1109 } 1110 1111 void view(vec2 pos, vec2 size) 1112 { 1113 //view_pos = pos * size - 1; 1114 view_size = vec2(2/size.x,2/size.y); 1115 sdl_transform = vec4(0,0,1.0/size.x,1.0/size.y); 1116 view_pos = (pos - size * 0.5) * view_size; 1117 } 1118 1119 // __gshared void function(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) __draw; 1120 __gshared void function(ref Renderer this_, scope ref const(DrawData) data) __draw; 1121 __gshared void function(ref Renderer this_) __present; 1122 __gshared void function(ref Renderer this_) __clear; 1123 __gshared void function(ref Renderer this_) __initialize; 1124 1125 static void __loadBackend() 1126 { 1127 //this.technique = __ecs_used_technique; 1128 if(technique == Technique.vbo_batch)__draw = &__draw_gl_vbo_batch; 1129 else __draw = &__draw_gl; 1130 __present = &__present_gl; 1131 __clear = &__clear_gl; 1132 __initialize = &__initialize_gl; 1133 } 1134 1135 }